From c12fcf8e7663c20e2c2c0696fb35a7059b83127a Mon Sep 17 00:00:00 2001 From: Joe Robinson Date: Tue, 8 Mar 2011 15:14:57 +0000 Subject: Implement weapons --- Level.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- Player.cpp | 26 ++++++++++++++++++++++++++ Player.h | 16 ++++++++++++++++ Projectile.cpp | 22 ++++++++++++++++++++++ Projectile.h | 19 +++++++++++++++++++ Shotgun.cpp | 24 ++++++++++++++++++++++++ Shotgun.h | 12 ++++++++++++ Weapon.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ Weapon.h | 29 +++++++++++++++++++++++++++++ intensemarcus.h | 2 ++ main.cpp | 10 +++++++++- projectiles.png | Bin 0 -> 3447 bytes weapons.png | Bin 0 -> 3730 bytes 14 files changed, 251 insertions(+), 2 deletions(-) create mode 100644 Projectile.cpp create mode 100644 Projectile.h create mode 100644 Shotgun.cpp create mode 100644 Shotgun.h create mode 100644 Weapon.cpp create mode 100644 Weapon.h create mode 100644 projectiles.png create mode 100644 weapons.png diff --git a/Level.cpp b/Level.cpp index 6655777..652284d 100644 --- a/Level.cpp +++ b/Level.cpp @@ -38,6 +38,11 @@ void Level::changeLevel(int levelNo) { player.setY(startY); cameraX = 0; + + // Give him some weapons + player.obtainWeapon(0); + player.obtainWeapon(1); + } void Level::move() { @@ -111,6 +116,33 @@ void Level::move() { } player.orient(); + + // Move the visible weapon with the player + player.weapon->setX(player.getX() + WEAPON_OFFSET_X); + player.weapon->setY(player.getY() + WEAPON_OFFSET_Y); + + // Move the projectiles + for (int i = 0; i < 10; i++) { + // Only calculate if they're active + if (player.weapon->projectiles[i].isActive()) { + // Move based on weapon speed + player.weapon->projectiles[i].setX(player.weapon->projectiles[i].getX() + player.weapon->getSpeed()); + if (player.weapon->projectiles[i].getX() + cameraX > SCREEN_WIDTH || player.weapon->projectiles[i].getY() > SCREEN_HEIGHT || player.weapon->projectiles[i].getX() < 0 || player.weapon->projectiles[i].getY() < 0) { + // If they go off screen, set to inactive + player.weapon->projectiles[i].setActive(false); + } + // Set up a collision box for the projectiles + SDL_Rect bullet; + bullet.x = player.weapon->projectiles[i].getX(); + bullet.y = player.weapon->projectiles[i].getY(); + bullet.w = 20; + bullet.h = 20; + // Check collision with objects + if (checkCollision(bullet)) { + player.weapon->projectiles[i].setActive(false); + } + } + } } void Level::draw(Screen *screen) { @@ -157,6 +189,16 @@ void Level::draw(Screen *screen) { hazard[0].image, hazard[i].getClip()); } } + + // Draw the player's weapon + screen->blit(player.weapon->getX() + cameraX, player.weapon->getY(), player.weapon->image, player.weapon->getClip()); + + // Draw each projectile, if it's active + for (int i = 0; i < 10; i++) { + if (player.weapon->projectiles[i].isActive()) { + screen->blit(player.weapon->projectiles[i].getX() + cameraX, player.weapon->projectiles[i].getY(), player.weapon->projectiles[i].image, player.weapon->projectiles[i].getClip()); + } + } } void Level::loadMap(int LevelNo) { diff --git a/Makefile b/Makefile index beeb011..c86efd7 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ CC = g++ intensemarcus: intensemarcus.h intensemarcus.cpp Creature.h Creature.cpp Hazard.h Hazard.cpp Level.h Level.cpp MapObject.h MapObject.cpp Monster.h Monster.cpp Pickup.h Pickup.cpp Platform.h Platform.cpp Player.h Player.cpp Screen.h Screen.cpp Sprite.h Sprite.cpp $(CC) -lSDL -lSDL_image main.cpp intensemarcus.cpp Creature.cpp \ Hazard.cpp Level.cpp MapObject.cpp Monster.cpp Pickup.cpp Platform.cpp \ - Player.cpp Screen.cpp Sprite.cpp -o intensemarcus + Player.cpp Screen.cpp Sprite.cpp Weapon.cpp Projectile.cpp Shotgun.cpp -o intensemarcus clean: intensemarcus rm -f intensemarcus diff --git a/Player.cpp b/Player.cpp index 09d1743..5995e4f 100644 --- a/Player.cpp +++ b/Player.cpp @@ -5,6 +5,7 @@ Player::Player() { health = 100; sprint = false; crouch = 0; + setWeapon(0); } void Player::jump() { @@ -66,3 +67,28 @@ void Player::orient() { int Player::getCrouch() { return crouch; } + +void Player::setWeapon(int weaponNo) { + // Set the current active weapon + weapon = weapons[weaponNo]; +} + +void Player::obtainWeapon(int weaponNo) { + // Add a new weapon to the available weapons + if (numWeapons < 10) { + switch (weaponNo) { + case 0: + weapons[numWeapons] = new Weapon(); + break; + case 1: + weapons[numWeapons] = new Shotgun(); + } + weapon = weapons[numWeapons]; + numWeapons++; + } +} + +void Player::attack() { + // Perform an attack with the current weapon + weapon->attack(); +} diff --git a/Player.h b/Player.h index 7c8cdf7..d866084 100644 --- a/Player.h +++ b/Player.h @@ -2,6 +2,8 @@ #define PLAYER_H #include "Creature.h" +#include "Weapon.h" +#include "Shotgun.h" class Player : public Creature { public: @@ -23,9 +25,23 @@ class Player : public Creature { void orient(); + void setWeapon(int weaponNo); + + void obtainWeapon(int weaponNo); + + void attack(); + + // Current active weapon + Weapon* weapon; + private: bool sprint; int crouch; + + // 10 weapons can be held at once + Weapon* weapons[10]; + int numWeapons; + int curWeapon; }; #endif diff --git a/Projectile.cpp b/Projectile.cpp new file mode 100644 index 0000000..38c3394 --- /dev/null +++ b/Projectile.cpp @@ -0,0 +1,22 @@ +#include +#include "Projectile.h" + +Projectile::Projectile() { + setImage("projectiles.png"); + setClip(0, 0, 0, 20, 20); + area = 1; + isVisible = false; + active = false; +} + +int Projectile::getArea() { + return area; +} + +bool Projectile::isActive() { + return active; +} + +void Projectile::setActive(bool a) { + active = a; +} diff --git a/Projectile.h b/Projectile.h new file mode 100644 index 0000000..af59cf0 --- /dev/null +++ b/Projectile.h @@ -0,0 +1,19 @@ +#ifndef PROJECTILE_H +#define PROJECTILE_H + +#include "Sprite.h" + +class Projectile : public Sprite { + public: + Projectile(); + + int getArea(); + bool isActive(); + void setActive(bool a); + + protected: + int area; + bool active; +}; + +#endif diff --git a/Shotgun.cpp b/Shotgun.cpp new file mode 100644 index 0000000..a265c26 --- /dev/null +++ b/Shotgun.cpp @@ -0,0 +1,24 @@ +#include "Shotgun.h" + +Shotgun::Shotgun() { + damage = 20; + speed = 5; + size = 1; + curProjectile = 0; + setImage("weapons.png"); + setClip(0, 100, 0, 100, 50); +} + +void Shotgun::attack() { + // Shoots 3 bullets in a row + for (int i = 0; i < 3; i++) { + projectiles[curProjectile].setX(getX() + 50); + projectiles[curProjectile].setY(getY() - 50 + (i * 30)); + projectiles[curProjectile].setActive(true); + if (curProjectile < 9) { + curProjectile++; + } else { + curProjectile = 0; + } + } +} diff --git a/Shotgun.h b/Shotgun.h new file mode 100644 index 0000000..0cfa69f --- /dev/null +++ b/Shotgun.h @@ -0,0 +1,12 @@ +#ifndef SHOTGUN_H +#define SHOTGUN_H + +#include "Weapon.h" + +class Shotgun : public Weapon { + public: + Shotgun(); + + void attack(); +}; +#endif diff --git a/Weapon.cpp b/Weapon.cpp new file mode 100644 index 0000000..9b04aa3 --- /dev/null +++ b/Weapon.cpp @@ -0,0 +1,49 @@ +#include +#include "Weapon.h" +#include "Projectile.h" + +Weapon::Weapon() { + damage = 1; + speed = 50; + size = 1; + curProjectile = 0; + setImage("weapons.png"); + setClip(0, 0, 0, 100, 50); +} + +int Weapon::getDamage() { + return damage; +} + +int Weapon::getSpeed() { + return speed; +} + +int Weapon::getSize() { + return size; +} + +void Weapon::setDamage(int damage) { + this->damage = damage; +} + +void Weapon::setSpeed(int speed) { + this->speed = speed; +} + +void Weapon::setSize(int size) { + this->size = size; +} + +void Weapon::attack() { + // Start the projectile at the end of the gun + projectiles[curProjectile].setX(getX() + 50); + projectiles[curProjectile].setY(getY() + 10); + projectiles[curProjectile].setActive(true); + // Use 10 projectiles then re-use from the beginning + if (curProjectile < 9) { + curProjectile++; + } else { + curProjectile = 0; + } +} diff --git a/Weapon.h b/Weapon.h new file mode 100644 index 0000000..32abf28 --- /dev/null +++ b/Weapon.h @@ -0,0 +1,29 @@ +#ifndef WEAPON_H +#define WEAPON_H + +#include "Sprite.h" +#include "Projectile.h" + +class Weapon : public Sprite { + public: + Weapon(); + + int getDamage(); + int getSpeed(); + int getSize(); + + void setDamage(int damage); + void setSpeed(int speed); + void setSize(int size); + + /* Virtual function, can be altered for + different weapon types. */ + virtual void attack(); + + // 10 projectiles on screen at one time + Projectile projectiles[10]; + + protected: + int damage, speed, size, x, y, curProjectile; +}; +#endif diff --git a/intensemarcus.h b/intensemarcus.h index 4484587..6c33ea7 100644 --- a/intensemarcus.h +++ b/intensemarcus.h @@ -24,6 +24,8 @@ const float SPRINT_MULTIPLYER = 1.5; const int MAP_X = 48; const int MAP_Y = 12; const int TILE_SIZE = 50; +const int WEAPON_OFFSET_X = 20; +const int WEAPON_OFFSET_Y = 50; SDL_Surface *loadImage(std::string filename); diff --git a/main.cpp b/main.cpp index b6e0a73..ecfd19d 100644 --- a/main.cpp +++ b/main.cpp @@ -46,7 +46,6 @@ int main(int argc, char* args[]) { break; case SDLK_UP: case SDLK_w: - case SDLK_SPACE: level.player.jump(); break; case SDLK_LCTRL: @@ -57,6 +56,15 @@ int main(int argc, char* args[]) { if (level.player.getCrouch() == 0) level.player.setCrouch(2); break; + case SDLK_SPACE: + level.player.attack(); + break; + case SDLK_0: + level.player.setWeapon(0); + break; + case SDLK_1: + level.player.setWeapon(1); + break; } } else if (event.type == SDL_KEYUP) { // Adjust player velocity diff --git a/projectiles.png b/projectiles.png new file mode 100644 index 0000000..4ba1230 Binary files /dev/null and b/projectiles.png differ diff --git a/weapons.png b/weapons.png new file mode 100644 index 0000000..962bd7a Binary files /dev/null and b/weapons.png differ -- cgit v1.2.3