Add Asteroid game
This commit is contained in:
68
CM2030 Graphics Programming/Topic 3/3.4.1/asteroidSystem.js
Normal file
68
CM2030 Graphics Programming/Topic 3/3.4.1/asteroidSystem.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
class AsteroidSystem {
|
||||||
|
|
||||||
|
//creates arrays to store each asteroid's data
|
||||||
|
constructor(){
|
||||||
|
this.locations = [];
|
||||||
|
this.velocities = [];
|
||||||
|
this.accelerations = [];
|
||||||
|
this.diams = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
run(multiplier){
|
||||||
|
this.spawn(multiplier);
|
||||||
|
this.move();
|
||||||
|
this.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
// spawns asteroid at random intervals
|
||||||
|
spawn(multiplier){
|
||||||
|
if (random(1) < 0.01 * multiplier){
|
||||||
|
this.accelerations.push(new createVector(0,random(0.1,1)));
|
||||||
|
this.velocities.push(new createVector(0, 0));
|
||||||
|
this.locations.push(new createVector(random(width), 0));
|
||||||
|
this.diams.push(random(30,50));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//moves all asteroids
|
||||||
|
move(){
|
||||||
|
for (var i=0; i<this.locations.length; i++){
|
||||||
|
this.velocities[i].add(this.accelerations[i]);
|
||||||
|
this.locations[i].add(this.velocities[i]);
|
||||||
|
this.accelerations[i].mult(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applyForce(f){
|
||||||
|
for (var i=0; i<this.locations.length; i++){
|
||||||
|
this.accelerations[i].add(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//draws all asteroids
|
||||||
|
draw(){
|
||||||
|
noStroke();
|
||||||
|
fill(200);
|
||||||
|
for (var i=0; i<this.locations.length; i++){
|
||||||
|
ellipse(this.locations[i].x, this.locations[i].y, this.diams[i], this.diams[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//function that calculates effect of gravity on each asteroid and accelerates it
|
||||||
|
calcGravity(centerOfMass){
|
||||||
|
for (var i=0; i<this.locations.length; i++){
|
||||||
|
var gravity = p5.Vector.sub(centerOfMass, this.locations[i]);
|
||||||
|
gravity.normalize();
|
||||||
|
gravity.mult(.001);
|
||||||
|
this.applyForce(gravity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//destroys all data associated with each asteroid
|
||||||
|
destroy(index){
|
||||||
|
this.locations.splice(index,1);
|
||||||
|
this.velocities.splice(index,1);
|
||||||
|
this.accelerations.splice(index,1);
|
||||||
|
this.diams.splice(index,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
58
CM2030 Graphics Programming/Topic 3/3.4.1/bulletSystem.js
Normal file
58
CM2030 Graphics Programming/Topic 3/3.4.1/bulletSystem.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
class BulletSystem {
|
||||||
|
constructor() {
|
||||||
|
this.bullets = [];
|
||||||
|
this.velocity = new createVector(0, -5);
|
||||||
|
this.diam = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
run() {
|
||||||
|
this.move();
|
||||||
|
this.draw();
|
||||||
|
this.edges();
|
||||||
|
}
|
||||||
|
|
||||||
|
fire(x, y) {
|
||||||
|
this.bullets.push(createVector(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
//draws all bullets
|
||||||
|
draw() {
|
||||||
|
fill(255);
|
||||||
|
for (var i = 0; i < this.bullets.length; i++) {
|
||||||
|
ellipse(this.bullets[i].x, this.bullets[i].y, this.diam, this.diam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//updates the location of all bullets
|
||||||
|
move() {
|
||||||
|
for (var i = 0; i < this.bullets.length; i++) {
|
||||||
|
this.bullets[i].y += this.velocity.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removeBullet(index) {
|
||||||
|
if (this.bullets.length <= 0 || index < 0 || index >= this.bullets.length)
|
||||||
|
return;
|
||||||
|
this.bullets.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//check if bullets leave the screen and remove them from the array
|
||||||
|
edges() {
|
||||||
|
// YOUR CODE HERE (3 lines approx)
|
||||||
|
let leftBound = 0;
|
||||||
|
let rightBound = width;
|
||||||
|
let topBound = 0;
|
||||||
|
let botBound = height;
|
||||||
|
|
||||||
|
for (let i = 0; i < this.bullets.length; i++) {
|
||||||
|
let bullet = this.bullets[i];
|
||||||
|
if (
|
||||||
|
bullet.y + this.diam < topBound ||
|
||||||
|
bullet.y - this.diam > botBound ||
|
||||||
|
bullet.x - this.diam > rightBound ||
|
||||||
|
bullet.x + this.diam < leftBound
|
||||||
|
)
|
||||||
|
this.removeBullet(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
CM2030 Graphics Programming/Topic 3/3.4.1/index.html
Normal file
25
CM2030 Graphics Programming/Topic 3/3.4.1/index.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>asteroids games clone</title>
|
||||||
|
<script src="libraries/p5.min.js" type="text/javascript"></script>
|
||||||
|
<script src="libraries/p5.sound.min.js" type="text/javascript"></script>
|
||||||
|
|
||||||
|
<script src="bulletSystem.js" type="text/javascript"></script>
|
||||||
|
<script src="asteroidSystem.js" type="text/javascript"></script>
|
||||||
|
<script src="spaceship.js" type="text/javascript"></script>
|
||||||
|
<script src="sketch.js" type="text/javascript"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
canvas {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body></body>
|
||||||
|
</html>
|
||||||
3
CM2030 Graphics Programming/Topic 3/3.4.1/libraries/p5.min.js
vendored
Normal file
3
CM2030 Graphics Programming/Topic 3/3.4.1/libraries/p5.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
28
CM2030 Graphics Programming/Topic 3/3.4.1/libraries/p5.sound.min.js
vendored
Normal file
28
CM2030 Graphics Programming/Topic 3/3.4.1/libraries/p5.sound.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
244
CM2030 Graphics Programming/Topic 3/3.4.1/sketch.js
Normal file
244
CM2030 Graphics Programming/Topic 3/3.4.1/sketch.js
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
var spaceship;
|
||||||
|
var asteroids;
|
||||||
|
var atmosphereLoc;
|
||||||
|
var atmosphereSize;
|
||||||
|
var earthLoc;
|
||||||
|
var earthSize;
|
||||||
|
var starLocs = [];
|
||||||
|
var playing;
|
||||||
|
var sizeL;
|
||||||
|
var sizeS;
|
||||||
|
var myCount;
|
||||||
|
var maxLives;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
function setup() {
|
||||||
|
createCanvas(1200, 800);
|
||||||
|
maxLives = 4;
|
||||||
|
spaceship = new Spaceship(maxLives);
|
||||||
|
asteroids = new AsteroidSystem();
|
||||||
|
|
||||||
|
//location and size of earth and its atmosphere
|
||||||
|
atmosphereLoc = new createVector(width / 2, height * 2.9);
|
||||||
|
atmosphereSize = new createVector(width * 3, width * 3);
|
||||||
|
earthLoc = new createVector(width / 2, height * 3.1);
|
||||||
|
earthSize = new createVector(width * 3, width * 3);
|
||||||
|
playing = true;
|
||||||
|
|
||||||
|
//graphical variables
|
||||||
|
sizeL = 50;
|
||||||
|
sizeS = 30;
|
||||||
|
myCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
function draw() {
|
||||||
|
background(0);
|
||||||
|
sky();
|
||||||
|
|
||||||
|
spaceship.run();
|
||||||
|
asteroids.run(myCount/1000); // To increase the asteroid spawning rate
|
||||||
|
|
||||||
|
drawEarth();
|
||||||
|
|
||||||
|
checkCollisions(spaceship, asteroids); // function that checks collision between various elements
|
||||||
|
|
||||||
|
drawGUI();
|
||||||
|
myCount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// GUI
|
||||||
|
function drawGUI()
|
||||||
|
{
|
||||||
|
// draw score
|
||||||
|
fill(0, 255, 0);
|
||||||
|
textAlign(LEFT);
|
||||||
|
textSize(sizeS);
|
||||||
|
text("Score: " + spaceship.score, 20, sizeS);
|
||||||
|
|
||||||
|
// draw player lives
|
||||||
|
fill(0, 255, 0);
|
||||||
|
for (let i = 0; i < spaceship.lives; i++) {
|
||||||
|
let locationX = width - spaceship.size - i * spaceship.size * 1.2;
|
||||||
|
let locationY = sizeS;
|
||||||
|
triangle(
|
||||||
|
locationX - spaceship.size/2, locationY + spaceship.size/2,
|
||||||
|
locationX + spaceship.size/2, locationY + spaceship.size/2,
|
||||||
|
locationX, locationY - spaceship.size/2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!playing)
|
||||||
|
{
|
||||||
|
fill(255);
|
||||||
|
textSize(80);
|
||||||
|
textAlign(CENTER);
|
||||||
|
if(spaceship.lives > 0)
|
||||||
|
{
|
||||||
|
textSize(sizeL);
|
||||||
|
text("You lost a life!", width / 2, height / 2);
|
||||||
|
textSize(sizeS);
|
||||||
|
text("press SPACE to continue", width / 2, height / 2 + sizeL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textSize(sizeL);
|
||||||
|
text("GAME OVER", width / 2, height / 2);
|
||||||
|
textSize(sizeS);
|
||||||
|
text("press SPACE to restart", width / 2, height / 2 + sizeL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
//draws earth and atmosphere
|
||||||
|
function drawEarth() {
|
||||||
|
noStroke();
|
||||||
|
//draw atmosphere
|
||||||
|
fill(0, 0, 255, 50);
|
||||||
|
ellipse(atmosphereLoc.x, atmosphereLoc.y, atmosphereSize.x, atmosphereSize.y);
|
||||||
|
//draw earth
|
||||||
|
fill(100, 255);
|
||||||
|
ellipse(earthLoc.x, earthLoc.y, earthSize.x, earthSize.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
//checks collisions between all types of bodies
|
||||||
|
function checkCollisions(spaceship, asteroids) {
|
||||||
|
//spaceship-2-asteroid collisions
|
||||||
|
//YOUR CODE HERE (2-3 lines approx)
|
||||||
|
for (let i = 0; i < asteroids.locations.length; i++) {
|
||||||
|
if (
|
||||||
|
isInside(
|
||||||
|
spaceship.location,
|
||||||
|
spaceship.size / 2,
|
||||||
|
asteroids.locations[i],
|
||||||
|
asteroids.diams[i] / 2
|
||||||
|
)
|
||||||
|
)
|
||||||
|
gameOver();
|
||||||
|
}
|
||||||
|
//asteroid-2-earth collisions
|
||||||
|
//YOUR CODE HERE (2-3 lines approx)
|
||||||
|
for (let i = 0; i < asteroids.locations.length; i++) {
|
||||||
|
if (
|
||||||
|
isInside(
|
||||||
|
earthLoc,
|
||||||
|
earthSize.y / 2,
|
||||||
|
asteroids.locations[i],
|
||||||
|
asteroids.diams[i] / 2
|
||||||
|
)
|
||||||
|
)
|
||||||
|
gameOver();
|
||||||
|
}
|
||||||
|
//spaceship-2-earth
|
||||||
|
//YOUR CODE HERE (1-2 lines approx)
|
||||||
|
if (
|
||||||
|
isInside(earthLoc, earthSize.y / 2, spaceship.location, spaceship.size / 2)
|
||||||
|
)
|
||||||
|
gameOver();
|
||||||
|
//spaceship-2-atmosphere
|
||||||
|
//YOUR CODE HERE (1-2 lines approx)
|
||||||
|
if (
|
||||||
|
isInside(
|
||||||
|
atmosphereLoc,
|
||||||
|
atmosphereSize.y / 2,
|
||||||
|
spaceship.location,
|
||||||
|
spaceship.size / 2
|
||||||
|
)
|
||||||
|
)
|
||||||
|
spaceship.setNearEarth();
|
||||||
|
//bullet collisions
|
||||||
|
//YOUR CODE HERE (3-4 lines approx)
|
||||||
|
for (let i = 0; i < spaceship.bulletSys.bullets.length; i++) {
|
||||||
|
for (let j = 0; j < asteroids.locations.length; j++) {
|
||||||
|
if (
|
||||||
|
isInside(
|
||||||
|
spaceship.bulletSys.bullets[i],
|
||||||
|
spaceship.bulletSys.diam,
|
||||||
|
asteroids.locations[j],
|
||||||
|
asteroids.diams[j] / 2
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
asteroids.destroy(j);
|
||||||
|
spaceship.score += 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
//helper function checking if there's collision between object A and object B
|
||||||
|
function isInside(locA, sizeA, locB, sizeB) {
|
||||||
|
// YOUR CODE HERE (3-5 lines approx)
|
||||||
|
if (dist(locA.x, locA.y, locB.x, locB.y) > sizeA + sizeB) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
function keyPressed() {
|
||||||
|
if(keyIsPressed && keyCode === 32) //spacebar
|
||||||
|
{
|
||||||
|
if(playing) //mid game, should shoot a bullet
|
||||||
|
{
|
||||||
|
spaceship.fire();
|
||||||
|
}
|
||||||
|
else //game stopped
|
||||||
|
{
|
||||||
|
if(spaceship.lives > 0) //has or more lives
|
||||||
|
{
|
||||||
|
continueGame();
|
||||||
|
}
|
||||||
|
else //no more lives left
|
||||||
|
{
|
||||||
|
restartGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//console.log(spaceship.bulletSys.bullets.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// function that ends the game by stopping the loops and displaying "Game Over"
|
||||||
|
function gameOver() {
|
||||||
|
spaceship.die();
|
||||||
|
playing = false;
|
||||||
|
myCount = 0;
|
||||||
|
noLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
function continueGame()
|
||||||
|
{
|
||||||
|
asteroids.locations = [];
|
||||||
|
asteroids.velocities = [];
|
||||||
|
asteroids.accelerations = [];
|
||||||
|
asteroids.diams = [];
|
||||||
|
spaceship.respawn();
|
||||||
|
playing = true;
|
||||||
|
loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
function restartGame()
|
||||||
|
{
|
||||||
|
continueGame();
|
||||||
|
spaceship.lives = maxLives;
|
||||||
|
spaceship.score = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// function that creates a star lit sky
|
||||||
|
function sky() {
|
||||||
|
push();
|
||||||
|
while (starLocs.length < 300) {
|
||||||
|
starLocs.push(new createVector(random(width), random(height)));
|
||||||
|
}
|
||||||
|
fill(255);
|
||||||
|
for (var i = 0; i < starLocs.length; i++) {
|
||||||
|
rect(starLocs[i].x, starLocs[i].y, 2, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (random(1) < 0.3) starLocs.splice(int(random(starLocs.length)), 1);
|
||||||
|
pop();
|
||||||
|
}
|
||||||
88
CM2030 Graphics Programming/Topic 3/3.4.1/spaceship.js
Normal file
88
CM2030 Graphics Programming/Topic 3/3.4.1/spaceship.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
class Spaceship {
|
||||||
|
constructor(lives) {
|
||||||
|
this.velocity = new createVector(0, 0);
|
||||||
|
this.location = new createVector(width / 2, height / 2);
|
||||||
|
this.acceleration = new createVector(0, 0);
|
||||||
|
this.maxVelocity = 5;
|
||||||
|
this.bulletSys = new BulletSystem();
|
||||||
|
this.size = 50;
|
||||||
|
this.lives = lives;
|
||||||
|
this.score = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
die() {
|
||||||
|
this.lives -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
respawn() {
|
||||||
|
this.velocity = new createVector(0, 0);
|
||||||
|
this.location = new createVector(width / 2, height / 2);
|
||||||
|
this.acceleration = new createVector(0, 0);
|
||||||
|
this.bulletSys = new BulletSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
run() {
|
||||||
|
this.bulletSys.run();
|
||||||
|
this.draw();
|
||||||
|
this.move();
|
||||||
|
this.edges();
|
||||||
|
this.interaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
draw() {
|
||||||
|
fill(125);
|
||||||
|
triangle(
|
||||||
|
this.location.x - this.size / 2,
|
||||||
|
this.location.y + this.size / 2,
|
||||||
|
this.location.x + this.size / 2,
|
||||||
|
this.location.y + this.size / 2,
|
||||||
|
this.location.x,
|
||||||
|
this.location.y - this.size / 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
move() {
|
||||||
|
let diff = this.velocity.add(this.acceleration);
|
||||||
|
this.velocity.add(this.acceleration);
|
||||||
|
this.velocity.limit(this.maxVelocity);
|
||||||
|
this.location.add(this.velocity);
|
||||||
|
this.acceleration.mult(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
applyForce(f) {
|
||||||
|
this.acceleration.add(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
interaction() {
|
||||||
|
if (keyIsDown(LEFT_ARROW)) {
|
||||||
|
this.applyForce(createVector(-0.1, 0));
|
||||||
|
}
|
||||||
|
if (keyIsDown(RIGHT_ARROW)) {
|
||||||
|
this.applyForce(createVector(0.1, 0));
|
||||||
|
}
|
||||||
|
if (keyIsDown(UP_ARROW)) {
|
||||||
|
this.applyForce(createVector(0, -0.1));
|
||||||
|
}
|
||||||
|
if (keyIsDown(DOWN_ARROW)) {
|
||||||
|
this.applyForce(createVector(0, 0.1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fire() {
|
||||||
|
this.bulletSys.fire(this.location.x, this.location.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
edges() {
|
||||||
|
if (this.location.x < 0) this.location.x = width;
|
||||||
|
else if (this.location.x > width) this.location.x = 0;
|
||||||
|
else if (this.location.y < 0) this.location.y = height;
|
||||||
|
else if (this.location.y > height) this.location.y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
setNearEarth() {
|
||||||
|
//YOUR CODE HERE (6 lines approx)
|
||||||
|
this.applyForce(new createVector(0, 0.05));
|
||||||
|
let friction = this.velocity.copy().mult(-1/30);
|
||||||
|
this.applyForce(friction);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user