Skip to content

Commit

Permalink
Merge pull request #2 from ayushpahwa/release
Browse files Browse the repository at this point in the history
feat: enemy collision and scoring mechanics
  • Loading branch information
ayushpahwa authored Dec 13, 2024
2 parents ad65d4e + 94dd523 commit 966d1bb
Show file tree
Hide file tree
Showing 10 changed files with 356 additions and 10 deletions.
103 changes: 103 additions & 0 deletions .git-branches.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Git Town configuration file
#
# Run "git town config setup" to add additional entries
# to this file after updating Git Town.
#
# The "push-hook" setting determines whether Git Town
# permits or prevents Git hooks while pushing branches.
# Hooks are enabled by default. If your Git hooks are slow,
# you can disable them to speed up branch syncing.
#
# When disabled, Git Town pushes using the "--no-verify" switch.
# More info at https://www.git-town.com/preferences/push-hook.
push-hook = true

# Should Git Town push the new branches it creates
# immediately to origin even if they are empty?
#
# When enabled, you can run "git push" right away
# but creating new branches is slower and
# it triggers an unnecessary CI run on the empty branch.
#
# When disabled, many Git Town commands execute faster
# and Git Town will create the missing tracking branch
# on the first run of "git sync".
push-new-branches = true

# Should "git ship" delete the tracking branch?
# You want to disable this if your code hosting platform
# (GitHub, GitLab, etc) deletes head branches when
# merging pull requests through its UI.
ship-delete-tracking-branch = false

# Should "git ship" sync branches before shipping them?
#
# Guidance: enable when shipping branches locally on your machine
# and disable when shipping feature branches via the code hosting
# API or web UI.
#
# When enabled, branches are always fully up to date when shipped
# and you get a chance to resolve merge conflicts
# between the feature branch to ship and the main development branch
# on the feature branch. This helps keep the main branch green.
# But this also triggers another CI run and delays shipping.
sync-before-ship = false

# Should "git sync" also fetch updates from the upstream remote?
#
# If an "upstream" remote exists, and this setting is enabled,
# "git sync" will also update the local main branch
# with commits from the main branch at the upstream remote.
#
# This is useful if the repository you work on is a fork,
# and you want to keep it in sync with the repo it was forked from.
sync-upstream = false

[branches]

# The main branch is the branch from which you cut new feature branches,
# and into which you ship feature branches when they are done.
# This branch is often called "main", "master", or "development".
main = "main"

# Perennial branches are long-lived branches.
# They are never shipped and have no ancestors.
# Typically, perennial branches have names like
# "development", "staging", "qa", "production", etc.
#
# See also the "perennial-regex" setting.
perennials = ["release"]

# All branches whose names match this regular expression
# are also considered perennial branches.
#
# If you are not sure, leave this empty.
perennial-regex = ""

[hosting]

# Knowing the type of code hosting platform allows Git Town
# to open browser URLs and talk to the code hosting API.
# Most people can leave this on "auto-detect".
# Only change this if your code hosting server uses as custom URL.
platform = "github"

# When using SSH identities, define the hostname
# of your source code repository. Only change this
# if the auto-detection does not work for you.
# origin-hostname = ""

[sync-strategy]

# How should Git Town synchronize feature branches?
# Feature branches are short-lived branches cut from
# the main branch and shipped back into the main branch.
# Typically you develop features and bug fixes on them,
# hence their name.
feature-branches = "merge"

# How should Git Town synchronize perennial branches?
# Perennial branches have no parent branch.
# The only updates they receive are additional commits
# made to their tracking branch somewhere else.
perennial-branches = "merge"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_Store
Binary file added assets/background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 12 additions & 4 deletions script.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
import StateManager from './src/stateManager.js'

// once all the HTML, CSS and other assets have loaded,
// we start with the JS init.
window.addEventListener("load", function() {

// get reference to the canvas object defined in the html page
const canvas = this.document.getElementById('canvas1');
const ctx = canvas.getContext("2d");
canvas.width = 600;
canvas.height = 800;
ctx.fillStyle = "white";
ctx.strokeStyle = "white";
ctx.lineWidth = 5;
ctx.font = "20px Impact";

const stateManager = new StateManager(canvas);


// clear rect and paint the whole scene again
function animate() {
// clear rect and paint the whole scene again
ctx.clearRect(0, 0, canvas.width, canvas.height)
stateManager.render(ctx);
// recursively calls this function to re-draw the updated components
window.requestAnimationFrame(animate);
}

// start the recursive loop for animation
animate();
}
)
})
2 changes: 1 addition & 1 deletion src/ammo.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class Ammo {
this.height = 20;
this.x = 0;
this.y = 0;
this.speed = 20;
this.speed = 30;
this.free = true;
this.stateManager = stateManager;
}
Expand Down
55 changes: 55 additions & 0 deletions src/enemy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
class Enemy {

constructor(stateManager, offsetInRaidX, offsetInRaidY) {
this.stateManager = stateManager;
this.enemyPosX = 0;
this.enemyPosY = 0;

// enemy hits and health
this.hitCounter = 0;
this.healthPoints = 1;

// the raid moves in a grid, the offset defines where the enemy is in the raid relative
// to the raid's x and y position
this.offsetInRaidX = offsetInRaidX;
this.offsetInRaidY = offsetInRaidY;
}

render(context) {
context.strokeRect(this.enemyPosX, this.enemyPosY, this.stateManager.enemySize, this.stateManager.enemySize);
}

// as the raid moves, add the offset to the enemy position and move it to
progress(raidPosX, raidPosY) {
this.enemyPosX = raidPosX + this.offsetInRaidX;
this.enemyPosY = raidPosY + this.offsetInRaidY;

// check if an enemy has crossed the lower bounds of the game
// if yes, finish the game
if (this.enemyPosY + this.stateManager.enemySize > this.stateManager.height) {
this.stateManager.gameOver = true;
}

// if the game is still going, check for enemy collisions active ammunitions
if (!this.stateManager.gameOver) {
// check for collisions
this.stateManager.availableAmmoPool.forEach(ammo => {
if (!ammo.free && this.stateManager.checkEnemyCollision(this, ammo)) {
this.hitCounter++;
ammo.reset();
if (!this.stateManager.gameOver)
this.stateManager.score++;
}
})

}

// check if enemy hit the player
if (this.stateManager.checkEnemyCollision(this, this.stateManager.player)) {
this.stateManager.player.lives--;
this.hitCounter++;
}
}
}

export default Enemy;
11 changes: 10 additions & 1 deletion src/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,24 @@ class Player {
this.stateManager = stateManager;
this.width = 100;
this.height = 100;
this.speed = 5;

// variables
this.lives = 3; // starting player with 3 lives
this.x = this.stateManager.width * 0.5 - this.width * 0.5;
this.y = this.stateManager.height - this.height;
this.speed = 5;
}

render(context) {
context.fillRect(this.x, this.y, this.width, this.height);
}

reset() {
this.lives = 3; // starting player with 3 lives
this.x = this.stateManager.width * 0.5 - this.width * 0.5;
this.y = this.stateManager.height - this.height;
}

update() {
// Handle intent to move left
if (this.stateManager.activeKeys.includes('ArrowLeft')
Expand Down
62 changes: 62 additions & 0 deletions src/raid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import Enemy from './enemy.js';

class Raid {
constructor(stateManager) {
this.stateManager = stateManager;

this.height = this.stateManager.enemyRaidGridRows * this.stateManager.enemySize;
this.width = this.stateManager.enemyRaidGridColumns * this.stateManager.enemySize;

this.raidPosX = 0;
// start the raid above the screen
this.raidPosY = -this.height;

this.speedX = 3;
this.speedY = 0;

this.enemies = [];
this.createEnemyRaid();
this.destroyed = false;
}

createEnemyRaid() {
for (let y = 0; y < this.stateManager.enemyRaidGridRows; y++) {
for (let x = 0; x < this.stateManager.enemyRaidGridColumns; x++) {
this.enemies.push(new Enemy(this.stateManager, x * this.stateManager.enemySize, y * this.stateManager.enemySize));
}
}
}

render(context) {
if (this.enemies.length <= 0) {
return;
}
if (this.raidPosY < 0) {
// if the raid has just spawned above the screen, float it down
this.speedY = 5;
} else {
// by default keep the vertical speed as 0 and update only when the horizontal limit is touched
this.speedY = 0;
}

// horizontal boundary check, if true, reverse the horizontal speed and increase the vertical speed by the height of the enemy
if (this.raidPosX > this.stateManager.width - this.width || this.raidPosX < 0) {
this.speedX *= -1;
this.speedY = this.stateManager.enemySize;
}

// udpate position of the wave
this.raidPosX += this.speedX;
this.raidPosY += this.speedY;

// update the position of the enemies in the wave relative to the wave position
this.enemies.forEach(enemy => {
enemy.progress(this.raidPosX, this.raidPosY);
enemy.render(context);
})

// check if the enemy is shot
this.enemies = this.enemies.filter(enemy => enemy.hitCounter < enemy.healthPoints);
}
}
export default Raid;
Loading

0 comments on commit 966d1bb

Please sign in to comment.