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