Trying to make Unending Boundaries In a Runner Game - runner

Trying to make a runner game. I don't want my character to fall off the edge of the map. How do I make the character always center of the path? I want to make so that my character is always center of the path as it is being instantiated and to never fall off the map.
public class GroundTile : MonoBehaviour
{
GroundSpawner groundSpawner;
// Start is called before the first frame update
private void Start()
{
groundSpawner = GameObject.FindObjectOfType<GroundSpawner>();
}
private void OnTriggerExit (Collider other)
{
groundSpawner.SpawnTile();
Destroy(gameObject, 2);
}
// Update is called once per frame
void Update()
{
}
}
public class GroundSpawner : MonoBehaviour
{
public GameObject groundTile;
Vector3 nextSpawnPoint;
// Start is called before the first frame update
public void SpawnTile()
{
GameObject temp = Instantiate(groundTile, nextSpawnPoint, Quaternion.identity);
nextSpawnPoint = temp.transform.GetChild(1).transform.position;
}
private void Start()
{
for (int i = 0; i < 10; i++)
{
SpawnTile();
}
}
}
I tried so many methods.

Related

Unable to identify where a NullPointerException is coming from

so I am getting the following error:
Exception in thread "Thread-0" java.lang.NullPointerException
at dev.tamir.firstgame.entities.creatures.Player.getInput(Player.java:19)
at dev.tamir.firstgame.entities.creatures.Player.tick(Player.java:31)
at dev.tamir.firstgame.states.GameState.tick(GameState.java:25)
at dev.tamir.firstgame.Game.tick(Game.java:65)
at dev.tamir.firstgame.Game.run(Game.java:110)
at java.lang.Thread.run(Unknown Source)
And I've checked all the lines Java had marked me and I can not find what is producing the null.
Player:
package dev.tamir.firstgame.entities.creatures;
import java.awt.Graphics;
import dev.tamir.firstgame.Game;
import dev.tamir.firstgame.gfx.Assets;
public class Player extends Creature {
private Game game;
public Player(Game game, float x, float y) {
super(game, x, y, Creature.DEFAULT_CREATURE_WIDTH, Creature.DEFAULT_CREATURE_HEIGHT);
}
#Override
public void tick() {
getInput();
move();
game.getGameCamera().centerOnEntity(this);
}
private void getInput() {
xMove = 0;
yMove = 0;
if(game.getKeyManager().up)
yMove = -speed;
if(game.getKeyManager().down)
yMove = speed;
if(game.getKeyManager().left)
xMove = -speed;
if(game.getKeyManager().right)
xMove = speed;
}
#Override
public void render(Graphics g) {
g.drawImage(Assets.robro[7], (int) (x - game.getGameCamera().getxOffset()), (int) (y - game.getGameCamera().getyOffset()), width, height, null);
}
}
Gamestate:
package dev.tamir.firstgame.states;
import java.awt.Graphics;
import dev.tamir.firstgame.Game;
import dev.tamir.firstgame.entities.creatures.Player;
import dev.tamir.firstgame.tiles.Tile;
import dev.tamir.firstgame.worlds.World;
public class GameState extends State {
private Player player;
private World world;
public GameState(Game game) {
super(game);
player = new Player(game, 0, 0);
world = new World(game, "res/worlds/world1.txt");
}
#Override
public void tick() {
world.tick();
player.tick();
}
#Override
public void render(Graphics g) {
world.render(g);
player.render(g);
}
}
Game:
package dev.tamir.firstgame;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import dev.tamir.firstgame.Display.Display;
import dev.tamir.firstgame.gfx.Assets;
import dev.tamir.firstgame.gfx.GameCamera;
import dev.tamir.firstgame.input.KeyManager;
import dev.tamir.firstgame.states.GameState;
import dev.tamir.firstgame.states.MenuState;
import dev.tamir.firstgame.states.State;
public class Game implements Runnable {
private Display display;
private Thread thread;
private BufferStrategy bs;
private Graphics g;
//States
private State gameState;
private State menuState;
//Input
private KeyManager keyManager;
//Camera
private GameCamera gameCamera;
private boolean running = false;
private int width, height;
public String title;
public Game(String title, int width, int height) {
this.width = width;
this.height = height;
this.title = title;
keyManager = new KeyManager();
}
private void init() {
display = new Display(title, width, height);
display.getFrame().addKeyListener(keyManager);
Assets.init();
gameCamera = new GameCamera(this, 0,0);
gameState = new GameState(this);
menuState = new MenuState(this);
State.setState(gameState);
}
private void tick() {
keyManager.tick();
if(State.getState() != null)
State.getState().tick();
}
private void render() {
bs = display.getCanvas().getBufferStrategy();
if(bs == null) {
display.getCanvas().createBufferStrategy(3);
return;
}
g = bs.getDrawGraphics();
//Clear
g.clearRect(0, 0, width, height);
//Draw
if(State.getState() != null)
State.getState().render(g);
//End of Draw
bs.show();
g.dispose();
}
public void run() {
init();
int fps = 60;
double timePerTick = 1000000000 / fps;
double delta = 0;
long now;
long lastTime = System.nanoTime();
long timer = 0;
int ticks = 0;
while (running) {
now = System.nanoTime();
delta += (now - lastTime) / timePerTick;
timer += now - lastTime;
lastTime = now;
if(delta >= 1) {
tick();
render();
ticks++;
delta--;
}
if(timer >= 1000000000) {
System.out.println("FPS: " + ticks );
ticks = 0;
timer = 0;
}
}
stop();
}
public KeyManager getKeyManager() {
return keyManager;
}
public GameCamera getGameCamera() {
return gameCamera;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public synchronized void start() {
if (running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop() {
if (!running)
return;
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
help would be very appreciated, as I've been looking for hours now and I don't know what is causing the null and I am suspecting the error log may even be misleading me.
My guess would be you have a private Game in your creature class. When you call super() in Player, you pass a Game object to Creature. The Creature constructor most likely has a line like this.game = game;
Of course, I can't say for sure because the Creature class is not included in your post, but that's the most likely code setup. Because game would then be private to Creature, Player cannot see it. That means the private Game game that you declare in Player is never set.
After you call super, do this.game = game;
This will almost certainly take care of your issue.
Just for future reference, the message you got when the error resulted is the call stack; basically it tells you what methods called what, the most recent being at the top. The error took place at line 19 in Player.getInput(), which was called by tick() in that same class.
The only object you use in getInput() is game, and so that must be the source of the null pointer. From there, it's a quick check to see that game is a private field of Player, and since it is null that's a huge clue that it was never initialized (though that is not always the case). Private fields most often are initialized in the class constuctor (but they don't have to be... your Player class is pretty sparse so it wouldn't take that long to look through all of it if you absolutly had to. Looking at the Player constructor, we see a Game object named game is passed in, which suggests that it was intended to be used to initialize game and yet never is. VoilĂ , we found the problem!
I'm sorry if that last paragraph felt a little condecending; it wasn't meant to be. I just wanted to walk you through how I found your issue. Hopefully knowing how I found it will help you find later errors on your own.

Making a highly customizable method, or a specific method that does a task?

I'm not really sure how I would phrase the title right, so I apologize for the initial confusion.
This is just a small question I had about how to structure code and such and I have no idea on what to call it so I will explain it with this example:
Say I am writing a Call of Duty type game where the player can customize their weapons with certain attachment.
I have a class that defines each gun. It looks something like this:
class Gun {
int clip = 30;
int ammo = 100;
float reloadTime = 5f;
float damage = 10f;
Attachment[] attachments;
//Plus some not included attachments.
void shoot() {
//...
}
void reload() {
//...
}
void applyAllAttachments() {
//Apply the list of attachments' effects
}
}
class Attachment {
void effect() {
//change the gun in some way.
}
}
Now I would like to add 4 attachments, Fast Mags (increase reload speed), Hollow Point (increase damage), Grenade Launcher (Secondary Gun) and Minigun (Replace the barrel with a minigun or something).
For the Fast Mags and the Hollow Point, it should be simple, all I have to do is change a number or a value, but for the Grenade Launcher and Minigun, which have custom, extra functions (like Unity Delegates), would it be wiser to add a function that handles external custom firing types, or would it be better to just have separate methods inside the Gun class that specifically handle to extra minigun functions?
TL;DR
If I want to add a grenade launcher attachment to a gun, should I do this:
class Gun {
int clip = 30;
int ammo = 100;
float reloadTime = 5f;
float damage = 10f;
Attachment[] attachments = Attachment[10];
//Plus some not included attachments.
void shoot() {
//...
customShoot();
}
void customShoot() {
//Apply attachments custom attachment shoot methods.
}
void reload() {
//...
}
void applyAllAttachments() {
//Apply the list of attachments' effects
}
}
class GrenadeLauncher extends Attachment {
#Override
public void effect() {
//Spawn new grenade
}
}
Or This:
class Gun {
int clip = 30;
int ammo = 100;
float reloadTime = 5f;
float damage = 10f;
Attachment[] attachments = Attachment[10];
//Plus some not included attachments.
void shoot() {
//...
if (attachments.GetType() == GrenadeLauncher) {
grenadeLauncherShoot();
}
}
void grenadeLauncherShoot() {
}
void reload() {
//...
}
void applyAllAttachments() {
//Apply the list of attachments' effects
}
}
Sorry for my pseudo/java code, hope it's comprehensible.
The first way is better: You can create new attachments without having to modify the Gun class.
In a general manner, you shouldn't need to check for type, and your code will be cleaner if you don't.
Here, your Attachment class should be abstract (I suppose it already is), and force children to implements some functions.
public abstract class Attachment
{
protected abstract void shoot();
}
Then the gun calls it for all Attachements:
class Gun {
int clip = 30;
int ammo = 100;
float reloadTime = 5f;
float damage = 10f;
Attachment[] attachments = Attachment[10];
//Plus some not included attachments.
void shoot() {
//...
for(int i = 0; i < attachments.length(); ++i) {
attachments[i].shoot();
}
}
void reload() {
//...
}
}
class GrenadeLauncher extends Attachment {
#Override
public void shoot()
{
//Spawn new grenade
}
}
By the way, why did you tag java and Unity? If you work with unity your code should be c# or javascript

How to morph an object at runtime while keeping past information?

Is it possible to morph an object at runtime depending on its current state and keep all past information?
Say I have the following (in pseudo-code):
class Vehicle {
int state, lat, long;
void run();
}
class Plane : Vehicle {
void run() {fly();}
}
class Car : Vehicle {
void run() {drive();}
}
class Boat : Vehicle {
void run() {navigate();}
}
void main() {
// Setup code goes here
Vehicle vehicle = new Vehicle();
while(true) {
switch(vehicle->state){
case(1): vehicle = new Plane();
case(2): vehicle = new Car();
case(3): vehicle = new Boat();
}
}
}
It is not possible in the sense you've wrote it, but it is possible to design system with behavior you want:
You have one object, it is the same object during runtime
Object has different behaviors
Current behavior is based on current state
Its small, but very important difference with what you wrote in question, in this approach we're not morphing object, but it's behavior only
There are could be multiple different implementations, depending on full set of requirements, here is simplest one, assuming that behavior changes position only:
class Position {
int lat, long;
}
interface PositionCalculator {
Position calc(Position old);
}
class Vehicle {
private Position pos;
void modify(PositionCalculator calc) {pos = calc.calc(pos);}
}
class CarCalculator : PositionCalculator {
Position calc(Position old) {return navigate(old);}
}
class PlaneCalculator : PositionCalculator {
Position calc(Position old) {return fly(old);}
}
void main() {
Vehicle vehicle = new Vehicle();
PositionCalculator plane = new PlaneCalculator()
PositionCalculator car = new CarCalculator();
while(true) {
if (vehicle is in air)
vehicle.modify(plane);
else if (vehicle is on road)
vehicle.modify(car);
}
}

Java - pressing a direction key and having it move smoothly

When I press a direction key to move the object in that direction, it moves once, pauses momentarily, then moves again. Kind of like how if I want to type "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", I would hold "a" key down, but after the first "a" there is a pause then the rest of the "a"'s are typed. How do I remove that pause in KeyListener? Thank you.
This is the key repetition feature that the OS provides, so there is no way around the pauses.
The way most games gets around this is to keep an array of the current state of all required keys and check periodically on them (for example in the game loop) and act on that (e.g move).
public class KTest extends JFrame implements KeyListener {
private boolean[] keyState = new boolean[256];
public static void main(String[] args) {
new KeyTest();
int xVelocity = 0;
int x = 0;
while(1) {
xVelocity = 0;
if(keyState[KeyEvent.VK_LEFT]) {
xVelocity = -5;
}
x += xVelocity;
}
}
KTest() {
this.addKeyListener(this);
}
void keyPressed(KeyEvent e) {
key_state[e.getKeyCode()] = true;
}
void keyReleased(KeyEvent e) {
key_state[e.getKeyCode()] = false;
}
}
Base class taken from: http://content.gpwiki.org/index.php/Java:Tutorials:Key_States

Static Initialization and Use of a Class in a Separate Module in D

In my program, I have a class that I want to be allocated before entering main(). I'd like to tuck these away in a separate module to keep the clutter out of my code; However, as soon as the module goes out of scope (before main() is entered), the objects are deallocated, leaving me trying to use a null reference in main. A short example:
// main.d
import SceneData;
int main(string[] argv)
{
start.onSceneEnter();
readln();
return 0;
}
// SceneData.d
import Scene;
public
{
Scene start;
}
static this()
{
Scene start = new Scene("start", "test", "test";
}
// Scene.d
import std.stdio;
class Scene
{
public
{
this(string name)
{
this.name = name;
}
this(string name, string descriptionOnEnter, string descriptionOnConnect)
{
this.name = name;
this.descriptionOnEnter = descriptionOnEnter;
this.descriptionOnConnect = descriptionOnConnect;
}
void onSceneEnter()
{
writeln(name);
writeln(descriptionOnEnter);
}
}
private
{
string name;
string descriptionOnEnter;
string descriptionOnConnect;
}
}
I'm still getting used to the concept of modules being the basic unit of encapsulation, as opposed to the class in C++ and Java. Is this possible to do in D, or must I move my initializations to the main module?
Here:
static this()
{
Scene start = new Scene("start", "test", "test");
}
"start" is a local scope variable that shadows global one. Global one is not initialized.
After I have changed this to:
static this()
{
start = new Scene("start", "test", "test");
}
Program crashed no more.