User Tools

Site Tools


shooty_ships

Shooty Ships

  • Roger and I created this game over 4 or 5 classes. It was an evolution of the bouncy balls demo series, itself which took 4 or 5 classes to cover.
  • This took place before we began learning python but after we had studied PHP.

fi.html

fi.html

<!DOCTYPE HTML>
<head>
<link rel="theme.css">
<script src="mygames.js"></script>
</head>
<html>
<body>

<span class="title">
	Fight IO
	<br>
	by Appledog
</span>

<hr>
<div id="score"></div>
<canvas id="myCanvas" style="border: 1px solid black;">
</canvas>
<hr>

<script>

// Set Up Canvas
	var MAX_W = 600;
	var MAX_H = 480;

	var canvas1 = document.getElementById('myCanvas');
	canvas1.width = MAX_W;
	canvas1.height = MAX_H;
	var ctx = canvas1.getContext('2d');





// Set Up Game
	var FPS = 60;

	var p1x = 100;
	var p1y = 100;
	var p1dx = 0;
	var p1dy = 0;

	var p2x = MAX_W-100;
	var p2y = MAX_H-100;
        var p2dx = 0;
	var p2dy = 0;

	var p1sx = 0;
	var p1sy = 0;
 	var p1sdx = 0;
	var p1sdy = 0;
	var p1s = 0;

	var p2sx = 0;
	var p2sy = 0;
	var p2sdx = 0;
	var p2sdy = 0;
	var p2s = 0;

	var gameSpeed = 10;
	var shipSize = 32;
	var p1score = 0;
	var p2score = 0;

	var p1a = 135;
	var p2a = 315;

// Set Up Animation Loop
// This will draw the game.
	setInterval(gameLoop, 1000/FPS);


// Set up controls
// Now you can control the ships.

    document.onkeydown = function(evt) {
        evt = evt || window.event;

	// STOP
	// P1: q
	if (evt.keyCode == 81) {
		p1dx = p1dx * 0.8;
		p1dy = p1dy * 0.8;
	}

	// P2: space bar
 	if (evt.keyCode == 32) {
		p2dx = p2dx * 0.8;
		p2dy = p2dx * 0.8;
	}



	// TURN LEFT
	// P1: a
        if (evt.keyCode == 65) {
		p1a = p1a - gameSpeed;
		if (p1a < 0) {
			p1a = p1a + 360;
		}
	}
	// P2: left arrow
        if (evt.keyCode == 37) {
		p2a = p2a - gameSpeed;
		if (p2a < 0) {
			p2a = p2a + 360;
		}
	}


	// RIGHT
	// P1: d
        if (evt.keyCode == 68) {
		p1a = p1a + gameSpeed;
		if (p1a > 360) {
			p1a = p1a - 360;
		}
	}
	// P2: right arrow
        if (evt.keyCode == 39) {
		p2a = p2a + gameSpeed;
		if (p2a > 360 ) {
			p2a = p2a - 360;
		}
	}






	// UP (Forward)
	// P1: a
        if (evt.keyCode == 87) {
		var radians = p1a * Math.PI / 180;
		var dx = Math.cos(radians);
		var dy = Math.sin(radians);	

		p1dx = p1dx - (dx * gameSpeed*4);
		p1dy = p1dy - (dy * gameSpeed*4);
	}

	// P2: up arrow
        if (evt.keyCode == 38) {
		var radians = p2a * Math.PI / 180;
		var dx = Math.cos(radians);
		var dy = Math.sin(radians);	

		p2dx = p2dx - (dx * gameSpeed*4);
		p2dy = p2dy - (dy * gameSpeed*4);
	}

	// DOWN (Reverse engines!)
	// P1: s
        if (evt.keyCode == 83) {
		var radians = p1a * Math.PI / 180;
		var dx = Math.cos(radians);
		var dy = Math.sin(radians);	

		p1dx = p1dx + (dx * gameSpeed*4);
		p1dy = p1dy + (dy * gameSpeed*4);
	}

	// P2: down arrow
        if (evt.keyCode == 40) {
		var radians = p2a * Math.PI / 180;
		var dx = Math.cos(radians);
		var dy = Math.sin(radians);	

		p2dx = p2dx + (dx * gameSpeed*4);
		p2dy = p2dy + (dy * gameSpeed*4);
	}


	// SHOOT
        // P1: e (69)
	if (evt.keyCode == 69) {
		shootGuns(1);
	}

	// P2: enter (13)
	if (evt.keyCode == 13) {
		shootGuns(2);
	}



	//alert (evt.keyCode);


    };

/////

function gameLoop() {
	moveShips();
	moveShots();
	checkRules();
	drawGame();
}

function moveShips() {
    p1x = p1x + p1dx/FPS;
    p1y = p1y + p1dy/FPS;
    p2x = p2x + p2dx/FPS;
    p2y = p2y + p2dy/FPS;
}

function moveShots() {
	if (p1s == 1) {
		p1sx = p1sx + p1sdx/FPS;
		p1sy = p1sy + p1sdy/FPS;
	}

	if (p2s == 1) {
		p2sx = p2sx + p2sdx/FPS;
		p2sy = p2sy + p2sdy/FPS;
	}
}

function checkRules() {
	checkShipsInside();
        checkShipsMaxSpeed();
	checkShots();
}

function checkShipsInside(){
	if (p1x > MAX_W) { p1x = 0; }
	if (p1y > MAX_H) { p1y = 0; }
	if (p2x > MAX_W) { p2x = 0; }
	if (p2y > MAX_H) { p2y = 0; }

	if (p1x < 0) { p1x = MAX_W; }
	if (p1y < 0) { p1y = MAX_H; }
	if (p2x < 0) { p2x = MAX_W; }
	if (p2y < 0) { p2y = MAX_H; }
}

function checkShipsMaxSpeed() {
	var p1speed = Math.abs(p1dx) + Math.abs(p1dy);
	var p2speed = Math.abs(p2dx) + Math.abs(p2dy);
	var MAX_SPEED = 1000;
	var BRAKES = 0.98;

	if (p1speed > MAX_SPEED) {
		p1dx = p1dx * BRAKES;
		p1dy = p1dy * BRAKES;
	}
	if (p2speed > MAX_SPEED) {
		p2dx = p2dx * BRAKES;
		p2dy = p2dy * BRAKES;
	}
}

function checkShots() {

	if (p1s == 1) {
		x = p2x;
                y = p2y;
                deg = p2a;
                width = 2*shipSize/3;
                height = shipSize;
		var pos0 = rotate(x, y, x, y - (height / 2), deg);
		var pos1 = rotate(x, y, x + (width / 2), y + (height / 2), deg);
		var pos2 = rotate(x, y, x - (width / 2), y + (height / 2), deg);
                x1 = pos0.x;
                x2 = pos1.x;
                x3 = pos2.x;
                y1 = pos0.y;
                y2 = pos1.y;
                y3 = pos2.y;
		if (isPointInTriangle(p1sx,p1sy,x1,y1,x2,y2,x3,y3)) {
			p1score = p1score + 1;
			p1s = 0;
		}

	}

	if (p2s == 1) {
		x = p1x;
                y = p1y;
                deg = p1a;
                width = 2*shipSize/3;
                height = shipSize;
		var pos0 = rotate(x, y, x, y - (height / 2), deg);
		var pos1 = rotate(x, y, x + (width / 2), y + (height / 2), deg);
		var pos2 = rotate(x, y, x - (width / 2), y + (height / 2), deg);
                x1 = pos0.x;
                x2 = pos1.x;
                x3 = pos2.x;
                y1 = pos0.y;
                y2 = pos1.y;
                y3 = pos2.y;
		if (isPointInTriangle(p2sx,p2sy,x1,y1,x2,y2,x3,y3)) {
			p2score = p2score + 1;
			p2s = 0;
		}

	}

}




function drawGame() {
	drawScore();
	
	clearScreen();
	drawShips();
	drawShoots();
}



function drawScore() {
	var scorediv = document.getElementById('score');

	var msg = "   Player 1: " + p1score.toFixed(0)
                   + ",  Player 2: " + p2score.toFixed(0);
       

	scorediv.innerHTML = msg;
}


function drawShips() {

	// Note x1,y1 is the direction.
	// We have:
	// p1a, p2a (angle)
	// p1x, p1y, p2x, p2y (location)

	drawShip(p1x, p1y, p1a, 2*shipSize/3, shipSize, "#FF0000");
	drawShip(p2x, p2y, p2a, 2*shipSize/3, shipSize, "#0000FF");

}

function shootGuns(p) {
	if (p == 1) {
		p1s = 1; // turn on the shoot.
		p1sx = p1x;
		p1sy = p1y;


		var radians = p1a * Math.PI / 180;
		var dx = Math.cos(radians);
		var dy = Math.sin(radians);	

		p1sdx = -1 * dx * gameSpeed*24;
		p1sdy = -1 * dy * gameSpeed*24;

	}
	if (p == 2) {
		p2s = 1;
		p2sx = p2x;
		p2sy = p2y;

		var radians = p2a * Math.PI / 180;
		var dx = Math.cos(radians);
		var dy = Math.sin(radians);	

		p2sdx = -1 * dx * gameSpeed*24;
		p2sdy = -1 * dy * gameSpeed*24;
	}
}

function drawShoots() {
	if (p1s == 1) {
		// draw p1 shot.
		var radius = 2;
		ctx.beginPath();
		ctx.arc(p1sx, p1sy, radius, 0, 2 * Math.PI, false);
    		ctx.fillStyle = "black";
    		ctx.fill();
    		ctx.lineWidth = 1;
    		ctx.strokeStyle = "black";
    		ctx.stroke();
	}

	if (p2s == 1) {
		// draw p2 shot.
		var radius = 2;
		ctx.beginPath();
		ctx.arc(p2sx, p2sy, radius, 0, 2 * Math.PI, false);
    		ctx.fillStyle = "black";
    		ctx.fill();
    		ctx.lineWidth = 1;
    		ctx.strokeStyle = "black";
    		ctx.stroke();
	}

}






function drawShip(x, y, deg, width, height, color) {
    var pos0 = rotate(x, y, x, y - (height / 2), deg);
    var pos1 = rotate(x, y, x + (width / 2), y + (height / 2), deg);
    var pos2 = rotate(x, y, x - (width / 2), y + (height / 2), deg);
                
    ctx.beginPath();
    ctx.moveTo(pos0.x, pos0.y);
    ctx.lineTo(pos1.x, pos1.y);
    ctx.lineTo(pos2.x, pos2.y);
    ctx.lineTo(pos0.x, pos0.y);
    ctx.stroke();
                
    ctx.fillStyle = color;
    ctx.fill();
}

// This function uses barycentric coordinates to determine whether a point
// is inside a triangle. The barycentric coordinates of a point with respect
// to a triangle are a set of three numbers (alpha, beta, gamma) that describe
// how the point can be expressed as a weighted sum of the vertices of the
// triangle. If all three numbers are positive, the point is inside the triangle.
// If any of the numbers is negative, the point is outside the triangle.

function isPointInTriangle(x, y, x1, y1, x2, y2, x3, y3) {
// Calculate the barycentric coordinates of the point with respect to the triangle
  const alpha = ((y2 - y3) * (x - x3) + (x3 - x2) * (y - y3)) /
                ((y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3));
  const beta = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) /
               ((y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3));
  const gamma = 1 - alpha - beta;
  
  // Check if the point is inside the triangle
  return alpha > 0 && beta > 0 && gamma > 0;
}



/////

</script>
</body>
</html>

mygames.js

You will also need this, which is a small library of functions we came up with as we learned javascript. The original idea of this was to help Roger understand how to make a library of functions in javascript.

mygames.js


function rotate(ox, oy, x, y, r) {
    var xDiff = x - ox;
    var yDiff = y - oy;
                
    var rot = Math.atan2(xDiff, yDiff);
    var newRot = rot + (r * 3.141592653 / 180);
                
    var dx = Math.cos(newRot); 
    var dy = Math.sin(newRot); 
                
    var dist = Math.sqrt((xDiff*xDiff)+(yDiff*yDiff));
                
    return {
        x: ox + (dx * dist), y: oy + (dy * dist)
    }
}


function getMousePos(canvas, event) {
    var rect = canvas.getBoundingClientRect();
    return {
        x: event.clientX - rect.left,
        y: event.clientY - rect.top
    };
}

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function getRandomColor() {
	var color = '';
	while (color.length != 7) {
		color = "#" + Math.random().toString(16).slice(2, 8);
	}
	return color;
}

function colorScreen(c) {
	ctx.fillStyle = c;
	ctx.fillRect(0, 0, MAX_W, MAX_H);
}

function clearScreen() {
	colorScreen("#FFFFFF");
}

theme.css

.title {
  font-size: 20px;
}

.mytd {
    border: 1px solid black;
    height: 50px;
    width: 50px;
}

shooty_ships.txt · Last modified: 2023/11/06 01:02 by appledog

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki