Need help adding shooting
in
Programming Questions
•
1 year ago
I'm working on making a game on the side of what I'm learning in class, I feel like the class is moving to slowly. However I'm having an issue adding shooting into my game. I've tried multiple techniques but all of them have failed to do what it is i'm trying to accomplish. I included the code for the game, basically I want the player to be able to shoot two bullets that when they hit the wall they change the walls color. Think portal if you have played it which is kinda what I want to do with my game. I'm very new to processing so hopefully someone can help!
// main class
// main class
- PImage character_stand, character_run1, character_run2, character_shoot, character_jumpshoot;
float cameraOffsetX;
Boolean gameover = false; //used for gameover screen
Boolean newGame = true; //used for title screen, implement if a new game is started display title screen
Player thePlayer = new Player();
World theWorld = new World();
Keyboard theKeyboard = new Keyboard();
//Bullet theBullet = new Bullet();
PFont font;
int gameStartTime, gameCurrentTime;
final float GRAVITY_STRENGTH = 0.65; // the lower, the higher player jumps
void setup() {
size(600, 480);
font = loadFont("SansSerif-20.vlw");
character_stand = loadImage("1.png");
character_run1 = loadImage("2.png");
character_run2 = loadImage("3.png");
character_shoot = loadImage("shoot.png");
character_jumpshoot = loadImage("jshoot.png");
ammo_fired = loadImage("bullet.png");
cameraOffsetX = 0.0;
frameRate(48);
resetGame();
}
void resetGame() {
gameover = false;
thePlayer.reset();
theWorld.reload(); //reset level
gameCurrentTime = gameStartTime = millis()/1000; // should be in seconds if dividing by 1000?
}
Boolean win() { //checks score for win
return (thePlayer.coinsCollected == theWorld.coinsInGame);
}
void textLetter(String sayThis, float atX, float atY) {
textFont(font);
fill(0);
text(sayThis, atX-1, atY);
text(sayThis, atX+1, atY);
text(sayThis, atX, atY-1);
text(sayThis, atX, atY+1);
fill(255);
text(sayThis, atX, atY);
}
void cameraPosition() {
int rightDistance = World.GRID_UNIT_WIDE * World.GRID_UNIT_SIZE - width;
cameraOffsetX = thePlayer.position.x - width / 2;
if (cameraOffsetX < 0) {
cameraOffsetX = 0;
}
if (cameraOffsetX > rightDistance) {
cameraOffsetX = rightDistance;
}
}
void draw() {
pushMatrix(); //should make for easy exit of translate, may be using this wrong... POP cancels this
translate(-cameraOffsetX, 0.0); //active until pop matrix, affects all graphics that follow
println(frameRate);
cameraPosition();
theWorld.render();
thePlayer.inputCheck();
thePlayer.move();
thePlayer.draw();
popMatrix(); //should exit from matrix and stop translate...
if (focused == false) {
textAlign(CENTER);
textLetter("Click here to play. \n\nUse arrows to move and jump.", width/2, height-90);
}
else {
textAlign(LEFT);
textLetter("Coins:"+thePlayer.coinsCollected +"/"+theWorld.coinsInGame, 8, height-10);
//textLetter("FPS:"+frameRate, 8, height-460); //fps counter if needed
textAlign(RIGHT);
if (win() == false) {
gameCurrentTime = millis()/1000; // dividing by 1000 to turn milliseconds into seconds
}
int minutes = (gameCurrentTime-gameStartTime)/60;
int seconds = (gameCurrentTime-gameStartTime)%60;
if (seconds < 10) {
textLetter(minutes +":0"+seconds, width-8, height-10);
}
else {
textLetter(minutes +":"+seconds, width-8, height-10);
}
textAlign(CENTER);
textLetter("p0rtals", width/2, 25);
if(gameCurrentTime < 6){
textLetter("Welcome to our testing facility.\nCollect all the coins to move on", width/2, 80);
}
if (win()) {
textLetter("You have collected all the Coins!\nPress R to reset game", width/2, height/2);
}
if (gameover) {
textFont(font, 20);
pushMatrix();
translate(0,0,0);
background(0);
text("You're terrible at this, we will find someone else...\n\nPress R to reset game", width/2, height/2);
popMatrix();
}
}
}
void keyPressed(KeyEvent evt) {
theKeyboard.pressedKey(evt.getKeyCode());
}
void keyReleased(KeyEvent evt) {
theKeyboard.releaseKey(evt.getKeyCode());
}
void stop() {
super.stop();
}
//player class
- class Player {
ArrayList bullets;
PVector position, velocity; //should contain x and y...
Boolean isOnLand; // is player on the ground?
Boolean isFacingRight; // is player facing right, used for flipping image
Boolean shoot;
int animationDelay;
int animationFrame;
int coinsCollected;
static final float JUMP_POWER = 10.0; //how fast player goes up
static final float RUN_SPEED = 5.0; //how fast player moves
static final float AIR_SPEED = 1.5; //affects movement in air
static final float SLOWDOWN_PREC = 0.4; //friction while on ground
static final float AIR_SLOWDOWN_PREC = 0.7; //friction while in air, makes it so player doesn't move super fast
static final float STAND_SPEED = 1.0; //this is the speed for when a player isn't moving, not sure if needed
static final int RUN_ANIMATION_DELAY = 3; //frames till animation updates
Player() {
shoot = true;
isOnLand = false;
isFacingRight = true;
position = new PVector();
velocity = new PVector();
reset();
}
void reset() {
coinsCollected = 0;
animationDelay = 0;
animationFrame = 0;
velocity.x = 0;
velocity.y = 0;
}
void inputCheck() {
float speedsHere = (isOnLand ? RUN_SPEED : AIR_SPEED);
float frictionsHere = (isOnLand ? SLOWDOWN_PREC : AIR_SLOWDOWN_PREC);
if (theKeyboard.holdS && theKeyboard.holdRight) {
velocity.x += speedsHere*2;
}
if (theKeyboard.holdS && theKeyboard.holdLeft) {
velocity.x -= speedsHere*2;
}
if (theKeyboard.holdSpace) {
}
if (theKeyboard.holdLeft) {
velocity.x -= speedsHere;
}
else if (theKeyboard.holdRight) {
velocity.x += speedsHere;
}
velocity.x *= frictionsHere; // this should cause player to constantly be losing speed...
if (isOnLand) { //player can only jump if on ground, change this for a double jump ability
if (theKeyboard.holdUp) {
velocity.y = -JUMP_POWER;
isOnLand = false;
}
}
}
void checkForWalls() {
int charWidth = character_stand.width; // image size
int charHeight = character_stand.height;
int wallDistance = int(charWidth * 0.5);
int ceilingDistance = int(charHeight * 0.95);
// detect wall/ceiling bumps
PVector rightLow, rightHigh, leftLow, leftHigh, topSide;
leftHigh = new PVector();
rightHigh = new PVector();
leftLow = new PVector();
rightLow = new PVector();
topSide = new PVector();
//update
leftHigh.x = leftLow.x = position.x - wallDistance; // left edge of player
rightHigh.x = rightLow.x = position.x + wallDistance; // right edge of player
leftLow.y = rightLow.y = position.y-0.3 * charHeight; // shin high
leftHigh.y = rightHigh.y = position.y-0.8 * charHeight; // shoulder high
topSide.x = position.x; // center of char
topSide.y = position.y-ceilingDistance; // top of char
//kill player and reset game
if (theWorld.worldSquareAt(topSide) == World.TILE_KILLBLOCK ||
theWorld.worldSquareAt(leftHigh) == World.TILE_KILLBLOCK ||
theWorld.worldSquareAt(leftLow) == World.TILE_KILLBLOCK ||
theWorld.worldSquareAt(rightHigh) == World.TILE_KILLBLOCK ||
theWorld.worldSquareAt(rightLow) == World.TILE_KILLBLOCK ||
theWorld.worldSquareAt(position) == World.TILE_KILLBLOCK)
{
gameover = true;
return;
}
if (theWorld.worldSquareAt(topSide)==World.TILE_SOLID || theWorld.worldSquareAt(topSide)==World.TILE_SOLID1) {
if (theWorld.worldSquareAt(position)==World.TILE_SOLID || theWorld.worldSquareAt(topSide)==World.TILE_SOLID1) {
position.sub(velocity);
velocity.x=0.0;
velocity.y=0.0;
}
else {
position.y = theWorld.bottomOfSquare(topSide)+ceilingDistance;
if (velocity.y < 0) {
velocity.y = 0.0;
}
}
}
if ( theWorld.worldSquareAt(leftLow)==World.TILE_SOLID || theWorld.worldSquareAt(leftLow)==World.TILE_SOLID1) {
position.x = theWorld.rightOfSquare(leftLow)+wallDistance;
if (velocity.x < 0) {
velocity.x = 0.0;
}
}
if ( theWorld.worldSquareAt(leftHigh)==World.TILE_SOLID || theWorld.worldSquareAt(leftHigh)==World.TILE_SOLID1) {
position.x = theWorld.rightOfSquare(leftHigh)+wallDistance;
if (velocity.x < 0) {
velocity.x = 0.0;
}
}
if ( theWorld.worldSquareAt(rightLow)==World.TILE_SOLID || theWorld.worldSquareAt(rightLow)==World.TILE_SOLID1) {
position.x = theWorld.leftOfSquare(rightLow)-wallDistance;
if (velocity.x > 0) {
velocity.x = 0.0;
}
}
if ( theWorld.worldSquareAt(rightHigh)==World.TILE_SOLID || theWorld.worldSquareAt(rightHigh)==World.TILE_SOLID1) {
position.x = theWorld.leftOfSquare(rightHigh)-wallDistance;
if (velocity.x > 0) {
velocity.x = 0.0;
}
}
}
void checkForCoinCollect() {
PVector centerOfPlayer;
PVector topOfPlayer;
centerOfPlayer = new PVector(position.x, position.y - character_stand.height/2);
topOfPlayer = new PVector(position.x, position.y - character_stand.height);
if (theWorld.worldSquareAt(centerOfPlayer) == World.TILE_COIN) {
theWorld.setSquareAtToThis(centerOfPlayer, World.TILE_EMPTY);
coinsCollected++;
}
if (theWorld.worldSquareAt(topOfPlayer) == World.TILE_COIN) {
theWorld.setSquareAtToThis(topOfPlayer, World.TILE_EMPTY);
coinsCollected++;
}
}
void checkFalling() {
if (theWorld.worldSquareAt(position)==World.TILE_EMPTY ||
theWorld.worldSquareAt(position)==World.TILE_COIN) {
isOnLand=false;
}
if (isOnLand == false) {
if (theWorld.worldSquareAt(position)==World.TILE_SOLID || theWorld.worldSquareAt(position)==World.TILE_SOLID1) { // landed on solid square?
isOnLand = true;
position.y = theWorld.topOfSquare(position);
velocity.y = 0.0;
}
else { // fall
velocity.y += GRAVITY_STRENGTH;
}
}
}
void move() {
position.add(velocity);
checkForWalls();
checkForCoinCollect();
checkFalling();
}
void draw() {
int guyWidth = character_stand.width;
int guyHeight = character_stand.height;
if (velocity.x < -STAND_SPEED) {
isFacingRight = false;
}
else if (velocity.x > STAND_SPEED) {
isFacingRight = true;
}
pushMatrix();
translate(position.x, position.y);
if (isFacingRight == false) {
scale(-1, 1);
}
translate(-guyWidth / 2, -guyHeight); // drawing images centered on character's feet
if (isOnLand == false) {
image(character_run1, 0, 0);
if (theKeyboard.holdSpace) {
image(character_jumpshoot, 0, 0);
}
}
else if (abs(velocity.x) < STAND_SPEED) {
image(character_stand, 0, 0);
}
else {
if (animationDelay--<0) {
animationDelay=RUN_ANIMATION_DELAY;
if (animationFrame==0) {
animationFrame=1;
}
else {
animationFrame=0;
}
}
if (animationFrame==0) {
image(character_run1, 0, 0);
}
else {
image(character_run2, 0, 0);
}
}
if (isOnLand == true) {
if (theKeyboard.holdSpace) {
if (!theKeyboard.holdLeft) {
if (!theKeyboard.holdRight) {
image(character_shoot, 0, 0);
//image(ammo_fired, 0, 0);
}
}
}
}
popMatrix(); // undoes all
}
}
// world class
- class World {
int coinsInGame;
int coinsUpdateTimer;
static final int TILE_EMPTY = 0;
static final int TILE_SOLID = 1;
static final int TILE_SOLID1 = 2;
static final int TILE_COIN = 3;
static final int TILE_KILLBLOCK = 4;
static final int TILE_START = 7;
static final int GRID_UNIT_SIZE = 30;
static final int GRID_UNIT_WIDE = 56;
static final int GRID_UNIT_TALL = 17;
int[][] worldGrid = new int[GRID_UNIT_TALL][GRID_UNIT_WIDE];
int[][] start_Grid = {}
World() {
coinsUpdateTimer = 0;
}
int worldSquareAt(PVector thisPosition) {
float gridSpotX = thisPosition.x / GRID_UNIT_SIZE;
float gridSpotY = thisPosition.y / GRID_UNIT_SIZE;
if(gridSpotX<0) {
return TILE_SOLID;
}
if(gridSpotX >= GRID_UNIT_WIDE) {
return TILE_SOLID;
}
if(gridSpotY < 0) {
return TILE_SOLID;
}
if(gridSpotY >= GRID_UNIT_TALL) {
return TILE_SOLID;
}
return worldGrid[int(gridSpotY)][int(gridSpotX)];
}
void setSquareAtToThis(PVector thisPosition, int newTile) {
int gridSpotX = int(thisPosition.x / GRID_UNIT_SIZE);
int gridSpotY = int(thisPosition.y / GRID_UNIT_SIZE);
if(gridSpotX < 0 || gridSpotX >= GRID_UNIT_WIDE ||
gridSpotY < 0 || gridSpotY >= GRID_UNIT_TALL) {
return;
}
worldGrid[gridSpotY][gridSpotX] = newTile;
}
float topOfSquare(PVector thisPosition) {
int thisY = int(thisPosition.y);
thisY /= GRID_UNIT_SIZE;
return float(thisY*GRID_UNIT_SIZE);
}
float bottomOfSquare(PVector thisPosition) {
if(thisPosition.y<0) {
return 0;
}
return topOfSquare(thisPosition)+GRID_UNIT_SIZE;
}
float leftOfSquare(PVector thisPosition) {
int thisX = int(thisPosition.x);
thisX /= GRID_UNIT_SIZE;
return float(thisX*GRID_UNIT_SIZE);
}
float rightOfSquare(PVector thisPosition) {
if(thisPosition.x<0) {
return 0;
}
return leftOfSquare(thisPosition)+GRID_UNIT_SIZE;
}
void reload() {
coinsInGame = 0; // we count them while copying in level data
for(int i=0; i < GRID_UNIT_WIDE; i++) {
for(int ii=0; ii < GRID_UNIT_TALL; ii++) {
if(start_Grid[ii][i] == TILE_START) { // player start position
worldGrid[ii][i] = TILE_EMPTY; // put an empty tile in that spot
// then update the player spot to the center of that tile
thePlayer.position.x = i * GRID_UNIT_SIZE + (GRID_UNIT_SIZE/2);
thePlayer.position.y = ii * GRID_UNIT_SIZE + (GRID_UNIT_SIZE/2);
} else {
if(start_Grid[ii][i]==TILE_COIN) {
coinsInGame++;
}
worldGrid[ii][i] = start_Grid[ii][i];
}
}
}
}
void render() { // draw the world
// these next few lines cycle a number we use to make it look like coins are spinning
coinsUpdateTimer--;
if(coinsUpdateTimer<-GRID_UNIT_SIZE/3) {
coinsUpdateTimer = GRID_UNIT_SIZE/3;
}
for(int i=0; i < GRID_UNIT_WIDE; i++) { // for each column
for(int ii=0; ii < GRID_UNIT_TALL; ii++) { // for each tile in that column
switch(worldGrid[ii][i]) { // check which tile type it is
case TILE_SOLID:
stroke(70);
fill(60);
break;
case TILE_KILLBLOCK:
stroke(0,198,198);
fill(0,198,198);
break;
case TILE_SOLID1:
stroke(200);
fill(220);
break;
default:
stroke(150);
fill(150);
break;
}
// then draw a rectangle
rect(i * GRID_UNIT_SIZE, ii * GRID_UNIT_SIZE, // x,y of top left corner to draw rectangle
GRID_UNIT_SIZE - 1, GRID_UNIT_SIZE - 1); // width, height of rectangle
if(worldGrid[ii][i]==TILE_COIN) {
stroke(224,89,0);
fill(12,161,255);
ellipse(i * GRID_UNIT_SIZE + (GRID_UNIT_SIZE/2), ii * GRID_UNIT_SIZE + (GRID_UNIT_SIZE/2), // center of grid spot
abs(coinsUpdateTimer), GRID_UNIT_SIZE/2); // spin size wide, 1/2 height of box tall
}
}
}
}
}
1