Professional Documents
Culture Documents
En la anterior entrega vimos como mover los objetos en un desplazamiento angular, y creamos un objeto que
sigue a nuestro jugador para todos lados. Con este conocimiento, crearemos un nuevo juego en esta entrega.
Un nuevo juego tan pronto? As es. Con los conocimientos que ya tenemos de juegos previos, y lo
recientemente aprendido, podemos crear un nuevo minijuego. Comencemos declarando las variables que
necesitaremos, t ya sabes la funcin de cada una:
var pause=true;
var gameover=true;
var score=0;
var eTimer=0;
var bombs=[];
Agreguemos tambin a nuestra funcin init, un escucha del ratn el cual, al presionar sobre nuestro canvas,
activar o desactivar la pausa respectivamente:
canvas.addEventListener('mousedown',function(evt){
pause=!pause;
},false);
Tu ya sabes crear el flujo del juego, as que me enfocar tan solo en los nuevos elementos. Como habrs
notado, tenemos un arreglo de bombas, que almacenarn nuestra lista de explosivos. Estos seguirn a
nuestro jugador por toda la pantalla, y tras un rato, explotarn. Para calcular el tiempo de explosin,
necesitaremos una nueva variable en nuestro crculo:
this.timer=0;
Agregamos ahora el temporizador. Cada 0.5 a 3 segundos, se agregar una nueva bomba:
Continuemos programando el comportamiento de las bombas. Primero, nos encargaremos de que cada
bomba siga al jugador, y restamos su temporizador en uno:
// Bombs
for(var i=0,l=bombs.length;i<l;i++){
bombs[i].timer-=deltaTime;
var angle=bombs[i].getAngle(player);
bombs[i].move(angle,speed*deltaTime);
Si el temporizador es menor a cero, ser el momento de la explosin de la bomba. Su radio se duplicar (Para
efecto de la explosin), y si la bomba est colisionando con el jugador, el juego terminar:
if(bombs[i].timer<0){
bombs[i].radius*=2;
if(bombs[i].distance(player)<0){
gameover=true;
pause=true;
}
}
}
Posteriormente eliminamos la bomba y aumentamos el puntuaje en uno. Para que la explosin sea dibujada
antes de eliminarle, haremos esto al siguiente turno, poniendo estas instrucciones al comienzo del ciclo for,
antes de restar su temporizador. Esto crear el efecto deseado:
if(bombs[i].timer<0){
score++;
bombs.splice(i--,1);
l--;
continue;
}
Por ltimo, dibujemos la bomba. Si esta est explotando, la rellenaremos de color blanco. Caso contrario, solo
dibujaremos su circunferencia; rojo en estado normal, e intercalar entre rojo y blanco cuando est por
explotar (Cuando el temporizador sea menor a 1 segundo):
for(var i=0,l=bombs.length;i<l;i++){
if(bombs[i].timer<0){
ctx.fillStyle='#fff';
bombs[i].fill(ctx);
}
else{
if(bombs[i].timer<1&&~~(bombs[i].timer*10)%2==0)
ctx.strokeStyle='#fff';
else
ctx.strokeStyle='#f00';
bombs[i].stroke(ctx);
}
}
Para hacer el efecto de que titile en esta ocasin, multiplicaremos el temporizador por 10 y lo convertimos a
enteros para obtener las dcimas de segundo. Ya de este valor, obtenemos su residuo entre dos, y si este es
0, se pintar su contorno de color blanco. El clculo permite que titile 5 veces antes de explotar.
Probamos ahora el juego. Veremos ahora que bombas son continuamente generadas de la esquina superior
derecha, y explotan tras un momento. Sin embargo, este juego no representa un verdadero reto. Agreguemos
algunas mejoras a la generacin de bombas:
this.speed=0;
Ahora, agreguemos velocidad a la bomba al ser creada:
bomb.speed=100+(random(score))*10;
A la velocidad base, le estoy sumando un valor al azar con la quinta fraccin del mximo valor del puntuaje
actual. Esto permitir no solo bombas veloces en niveles ms altos, si no adems, bombas con diferentes
velocidades, lo que har que evadirlas sea ms difcil.
Por ltimo, no olvides mover las bombas de acuerdo a su velocidad:
bombs[i].move(angle,bombs[i].speed*deltaTime);
Ahora s! Disfrutemos de nuestro nuevo juego. Con tan solo conocer las bases de un nuevo tipo de
movimiento, y todo lo aprendido, pudimos crear un juego totalmente nuevo para nuestra coleccin, prueba del
aprendizaje que has adquirido durante este curso. Y con esto tambin, concluimos el curso bsico de uso del
ratn en juegos. Como siempre, las dudas que tengas, puedes dejarlas en los comentarios. Felices cdigos!
Cdigo final:
(function(){
'use strict';
window.addEventListener('load',init,false);
var canvas=null,ctx=null;
var mousex=0,mousey=0;
var lastUpdate=0;
var pause=true;
var gameover=true;
var score=0;
var eTimer=0;
var player=new Circle(0,0,5);
var bombs=[];
function random(max){
return ~~(Math.random()*max);
}
function init(){
canvas=document.getElementById('canvas');
ctx=canvas.getContext('2d');
canvas.width=300;
canvas.height=200;
enableInputs();
run();
}
function run(){
requestAnimationFrame(run);
var now=Date.now();
var deltaTime=(now-lastUpdate)/1000;
if(deltaTime>1)deltaTime=0;
lastUpdate=now;
act(deltaTime);
paint(ctx);
}
function reset(){
score=0;
eTimer=0;
bombs.length=0;
gameover=false;
}
function act(deltaTime){
if(!pause){
// GameOver Reset
if(gameover)
reset();
// Move player
player.x=mousex;
player.y=mousey;
// Keep player in canvas
if(player.x<0)
player.x=0;
if(player.x>canvas.width)
player.x=canvas.width;
if(player.y<0)
player.y=0;
if(player.y>canvas.height)
player.y=canvas.height;
// Generate new bomb
eTimer-=deltaTime;
if(eTimer<0){
var bomb=new Circle(random(2)*canvas.width,random(2)*canvas.height,10);
bomb.timer=1.5+random(2.5);
bomb.speed=100+(random(score))*10;
bombs.push(bomb);
eTimer=0.5+random(2.5);
}
// Bombs
for(var i=0,l=bombs.length;i<l;i++){
if(bombs[i].timer<0){
score++;
bombs.splice(i--,1);
l--;
continue;
}
bombs[i].timer-=deltaTime;
var angle=bombs[i].getAngle(player);
bombs[i].move(angle,bombs[i].speed*deltaTime);
if(bombs[i].timer<0){
bombs[i].radius*=2;
if(bombs[i].distance(player)<0){
gameover=true;
pause=true;
}
}
}
}
}
function paint(ctx){
ctx.fillStyle='#000';
ctx.fillRect(0,0,canvas.width,canvas.height);
for(var i=0,l=bombs.length;i<l;i++){
if(bombs[i].timer<0){
ctx.fillStyle='#fff';
bombs[i].fill(ctx);
}
else{
if(bombs[i].timer<1&&~~(bombs[i].timer*10)%2==0)
ctx.strokeStyle='#fff';
else
ctx.strokeStyle='#f00';
bombs[i].stroke(ctx);
}
}
ctx.strokeStyle='#0f0';
player.stroke(ctx);
ctx.fillStyle='#fff';
//ctx.fillText('Distance: '+player.distance(bombs[0]).toFixed(1),10,10);
//ctx.fillText('Angle: '+(player.getAngle(bombs[0])*(180/Math.PI)).toFixed(1),10,20);
ctx.fillText('Score: '+score,10,10);
if(pause){
ctx.textAlign='center';
if(gameover)
ctx.fillText('GAME OVER',150,100);
else
ctx.fillText('PAUSE',150,100);
ctx.textAlign='left';
}
}
function enableInputs(){
document.addEventListener('mousemove',function(evt){
mousex=evt.pageX-canvas.offsetLeft;
mousey=evt.pageY-canvas.offsetTop;
},false);
canvas.addEventListener('mousedown',function(evt){
pause=!pause;
},false);
}
function Circle(x,y,radius){
this.x=(x==null)?0:x;
this.y=(y==null)?0:y;
this.radius=(radius==null)?0:radius;
this.timer=0;
this.speed=0;
}
Circle.prototype.distance=function(circle){
if(circle!=null){
var dx=this.x-circle.x;
var dy=this.y-circle.y;
return(Math.sqrt(dx*dx+dy*dy)-(this.radius+circle.radius));
}
}
Circle.prototype.getAngle=function(circle){
if(circle!=null)
return(Math.atan2(circle.y-this.y,circle.x-this.x));
}
Circle.prototype.move=function(angle,speed){
if(speed!=null){
this.x+=Math.cos(angle)*speed;
this.y+=Math.sin(angle)*speed;
}
}
Circle.prototype.stroke=function(ctx){
ctx.beginPath();
ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,true);
ctx.stroke();
}
Circle.prototype.fill=function(ctx){
ctx.beginPath();
ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,true);
ctx.fill();
}
window.requestAnimationFrame=(function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function(callback){window.setTimeout(callback,17);};
})();
})();
Publicado por Karl Tayfer en 3:00
Enviar por correo electrnicoEscribe un blogCompartir con TwitterCompartir con FacebookCompartir en Pinterest
Buenas renegando un poco pude lograr lo que queria que es poder crear bombas que luego exploten. dejo
el
script
por
si
alguien
le
interesa
window.addEventListener('load',init,false);
var
canvas=null,ctx=null;
var
lastKey=null;
var
mousex=0,mousey=0;
var
boom=3;
var
player=new
Circle(0,0,5);
var
eTimer=0;
//var
enemies=new
Circle(100,100,10);
var
enemies=[];
var
wall=[];
var
map1=[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1];
var
target=new
Circle(100,100,10);
function
var
var
wall.length=0;
for(var
row++;
col=0;
}
}
}
function
canvas=document.getElementById('canvas');
canvas.style.background='#000';
ctx=canvas.getContext('2d');
setMap(map,columns,blockSize){
col=0;
row=0;
i=0,l=map.length;i=columns){
init(){
enableInputs();
setMap(map1,30,20);
run();
}
function
return
}
random(max){
~~(Math.random()*max);
function
setTimeout(run,50);
game();
paint(ctx);
}
run(){
function
player.x=mousex;
player.y=mousey;
game(){
if(player.x<0)
player.x=0;
if(player.x>canvas.width)
player.x=canvas.width;
if(player.y<0)
player.y=0;
if(player.y>canvas.height)
player.y=canvas.height;
eTimer--;
if(lastKey==1){
canvas.style.background='#333';
if(player.distance(target)<0){
boom+=3;
target.x=random(canvas.width/10-1)*10+target.radius;
target.y=random(canvas.height/10-1)*10+target.radius;
}else
//enemies.push(new
//var
enemie=new
enemies.push(new
boom--;
//
//enemies.timer=50+random(50);
eTimer=10+random(50);
}
}else{
canvas.style.background='#000';
}
//
/*for(var
//enemies.splice(i--,1);
enemies[i].y-=5;
Move
if(boom>0){
Rectangle(player.x,player.y,30,30));
Circle(player.x,player.y,10);
Circle(player.x,player.y,10));
enemies.push(enemie);
Shots
i=0;icanvas.height-30){
}else
enemies[i].radius*=2;
if(enemies[i].timer==0){
}
}
}
function
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.fillStyle='#999';
for(var
this.yrect.y);
}
}
}
function
this.x=(x==null)?0:x;
this.y=(y==null)?0:y;
this.radius=(radius==null)?0:radius;
this.timer=30;
this.distance=function(circle){
if(circle!=null){
var
var
return
}
}
}
Direcciona
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Traffic Lights</title>
<style type="text/css">
#page
{
width: 300px;
height: 500px;
margin: auto;
}
#canvas:hover
{
cursor: crosshair;
background-color: #191919;
}
paint(ctx){
i=0,l=wall.length;irect.x&&
Circle(x,y,radius){
dx=this.x-circle.x;
dy=this.y-circle.y;
(Math.sqrt(dx*dx+dy*dy)-(this.radius+circle.radius));
#canvas
{
background-color: #252525;
}
body
{
background: #222222;
color: white;
}
</style>
<script type="text/javascript">
var RED = "#FF0000";
var YELLOW = "#FFFF00";
var GREEN = "#00FF00";
var DARK_RED = "#380000";
var DARK_YELLOW = "#383800";
var DARK_GREEN = "#003800";
var
var
var
var
X_ALL = 150;
Y_RED = 100;
Y_YELLOW = Y_RED + 150;
Y_GREEN = Y_YELLOW + 150;
var trafficLightsStateMachine;
function TrafficLightsStateMachine() {
this.state = 0;
this.stateMachine = new Array();
this.stateMachine[0]
DARK_GREEN); };
this.stateMachine[1]
DARK_GREEN); };
this.stateMachine[2]
this.stateMachine[3]
GREEN); };
this.process = function() {
this.stateMachine[this.state]();
this.state = (this.state + 1) % this.stateMachine.length;
};
this.drawCircle = function(canvas, color, x, y) {
var context = canvas.getContext('2d');
context.strokeStyle = "#000000";
context.fillStyle = color;
context.beginPath();
context.arc(x, y, 50, 0, Math.PI * 2, true);
context.closePath();
context.stroke();
context.fill();
};
}
function drawCircles(first, second, third) {
var id = 'canvas';
var canvas = document.getElementById(id);
if (canvas.getContext) {
trafficLightsStateMachine.drawCircle(canvas, first, X_ALL, Y_RED);
trafficLightsStateMachine.drawCircle(canvas, second, X_ALL, Y_YELLOW);
trafficLightsStateMachine.drawCircle(canvas, third, X_ALL, Y_GREEN);
}
}
function init() {
trafficLightsStateMachine = new TrafficLightsStateMachine();
drawCircles(DARK_RED, DARK_YELLOW, GREEN);
}
</script>
</head>
<body onload="init()">
<div id="page" onclick="trafficLightsStateMachine.process()" title="Please,
press button.">
<canvas id="canvas" height="500px" width="300px">
<p>Your browser doesn't support canvas.</p>
</canvas>
</div>
</body>
</html>
canvas.addEventListener('mousedown',function(evt){
pause=!pause;
},false);
this.timer=0;
// Bombs
for(var i=0,l=bombs.length;i<l;i++){
bombs[i].timer-=deltaTime;
var angle=bombs[i].getAngle(player);
bombs[i].move(angle,speed*deltaTime);
if(bombs[i].timer<0){
bombs[i].radius*=2;
if(bombs[i].distance(player)<0){
gameover=true;
pause=true;
}
}
}
if(bombs[i].timer<0){
score++;
bombs.splice(i--,1);
l--;
continue;
}
for(var i=0,l=bombs.length;i<l;i++){
if(bombs[i].timer<0){
ctx.fillStyle='#fff';
bombs[i].fill(ctx);
}
else{
if(bombs[i].timer<1&&~~(bombs[i].timer*10)%2==0)
ctx.strokeStyle='#fff';
else
ctx.strokeStyle='#f00';
bombs[i].stroke(ctx);
}
}
this.speed=0;
bomb.speed=100+(random(score))*10;
bombs[i].move(angle,bombs[i].speed*deltaTime);
(function(){
'use strict';
window.addEventListener('load',init,false);
var canvas=null,ctx=null;
var mousex=0,mousey=0;
var lastUpdate=0;
var pause=true;
var gameover=true;
var score=0;
var eTimer=0;
var player=new Circle(0,0,5);
var bombs=[];
function random(max){
return ~~(Math.random()*max);
}
function init(){
canvas=document.getElementById('canvas');
ctx=canvas.getContext('2d');
canvas.width=300;
canvas.height=200;
enableInputs();
run();
}
function run(){
requestAnimationFrame(run);
var now=Date.now();
var deltaTime=(now-lastUpdate)/1000;
if(deltaTime>1)deltaTime=0;
lastUpdate=now;
act(deltaTime);
paint(ctx);
}
function reset(){
score=0;
eTimer=0;
bombs.length=0;
gameover=false;
}
function act(deltaTime){
if(!pause){
// GameOver Reset
if(gameover)
reset();
// Move player
player.x=mousex;
player.y=mousey;
*canvas.height,10);
bomb.timer=1.5+random(2.5);
bomb.speed=100+(random(score))*10;
bombs.push(bomb);
eTimer=0.5+random(2.5);
}
// Bombs
for(var i=0,l=bombs.length;i<l;i++){
if(bombs[i].timer<0){
score++;
bombs.splice(i--,1);
l--;
continue;
}
bombs[i].timer-=deltaTime;
var angle=bombs[i].getAngle(player);
bombs[i].move(angle,bombs[i].speed*deltaTime);
if(bombs[i].timer<0){
bombs[i].radius*=2;
if(bombs[i].distance(player)<0){
gameover=true;
pause=true;
}
}
}
}
}
function paint(ctx){
ctx.fillStyle='#000';
ctx.fillRect(0,0,canvas.width,canvas.height);
for(var i=0,l=bombs.length;i<l;i++){
if(bombs[i].timer<0){
ctx.fillStyle='#fff';
bombs[i].fill(ctx);
}
else{
if(bombs[i].timer<1&&~~(bombs[i].timer*10)%2==0)
ctx.strokeStyle='#fff';
else
ctx.strokeStyle='#f00';
bombs[i].stroke(ctx);
}
}
ctx.strokeStyle='#0f0';
player.stroke(ctx);
ctx.fillStyle='#fff';
//ctx.fillText('Distance: '+player.distance(bombs[0]).toFixed(1),10,10);
//ctx.fillText('Angle: '+(player.getAngle(bombs[0])*
(180/Math.PI)).toFixed(1),10,20);
ctx.fillText('Score: '+score,10,10);
if(pause){
ctx.textAlign='center';
if(gameover)
ctx.fillText('GAME OVER',150,100);
else
ctx.fillText('PAUSE',150,100);
ctx.textAlign='left';
}
}
function enableInputs(){
document.addEventListener('mousemove',function(evt){
mousex=evt.pageX-canvas.offsetLeft;
mousey=evt.pageY-canvas.offsetTop;
},false);
canvas.addEventListener('mousedown',function(evt){
pause=!pause;
},false);
}
function Circle(x,y,radius){
this.x=(x==null)?0:x;
this.y=(y==null)?0:y;
this.radius=(radius==null)?0:radius;
this.timer=0;
this.speed=0;
}
Circle.prototype.distance=function(circle){
if(circle!=null){
var dx=this.x-circle.x;
var dy=this.y-circle.y;
return (Math.sqrt(dx*dx+dy*dy)-(this.radius+circle.radius));
}
}
Circle.prototype.getAngle=function(circle){
if(circle!=null)
return (Math.atan2(circle.y-this.y,circle.x-this.x));
}
Circle.prototype.move=function(angle,speed){
if(speed!=null){
this.x+=Math.cos(angle)*speed;
this.y+=Math.sin(angle)*speed;
}
}
Circle.prototype.stroke=function(ctx){
ctx.beginPath();
ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,true);
ctx.stroke();
}
Circle.prototype.fill=function(ctx){
ctx.beginPath();
ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,true);
ctx.fill();
window.requestAnimationFrame=(function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function(callback){window.setTimeout(callback,17);};
})();
})();
1.
2.
3.
4.
5.
6.
7.
Mensaje
Accin sugerida
OK
Calibrar
No hay
batera
Desconoci
do
Dbil
o
Muy dbil
Reemplaz
ar
5.
6.
7.
8.
Calibrar
Reemplazar
No hay batera
Para cada resultado que vea, aparecern instrucciones en pantalla. Siga
las instrucciones para calibrar o reemplazar la batera, segn sea
necesario.
1.
2.
3.
Paso
1.
2.
3.
4.
4.
3.