I am trying to make a code where planes are added to make a road. The camera follows the player, and when a ground plane reaches the center, a new one is added after it. When a ground plane reaches a certain point that is off the screen, it gets deleted.
Here’s my current code:
import bge
scene = bge.logic.getCurrentScene()
cont = bge.logic.getCurrentController()
cam = scene.active_camera
own = cont.owner
center = scene.objects["Center"]
if "groundList" not in own:
own["groundList"] = []
while own["tap"] == False: #run once
ground = scene.addObject("Ground", "GroundGen", 0)
ground.worldPosition = center.worldPosition
own["groundList"].append(ground)
own["tap"] = True
else: #run always after that
for obj in own["groundList"]:
if obj.worldPosition.y <= center.worldPosition.y - 15.0: #remove obj when its not on screen anymore
own["groundList"].remove(obj)
obj.endObject()
if obj.worldPosition.y <= center.worldPosition.y and len(own["groundList"]) < 2: #add a new ground when another one reaches the center
newGround = scene.addObject("Ground", "GroundGen", 0)
own["groundList"].append(newGround)
The first plane added does what it needs to do, but the rest don’t do anything. Can anyone tell me why?
The “Center” object moves forward with the player, but the “GroundGen” object does not. Once the player moves past it, the ground objects are spawned behind the player and immediately removed. You should probably parent “GroundGen” to “Center” to achieve the effect you want.
Side Note: Most games that have some form of infinitely scrolling terrain will actually have the terrain move backwards and keep the player stationary instead of moving the player forward. This prevents you from running into issues with floating-point precision as the player moves very far from the world origin.
I knew it was some silly mistake!!! Anyway, thanks
Cotaks, I have looked at your infinite runner and it’s great, but I’d rather try making my own, so I can learn.
Cotaks, I have looked at your infinite runner and it’s great, but I’d rather try making my own, so I can learn.
That is the best way! anyway some advice, dont use a while loop, just put the code from the while loop into the ‘if “groundList” not in own:’
that already runs only once, so it can execute the other 1 timer coding as well.
import bge
scene = bge.logic.getCurrentScene()
cont = bge.logic.getCurrentController()
cam = scene.active_camera
own = cont.owner
center = scene.objects["Center"]
if "groundList" not in own:
own["groundList"] = []
ground = scene.addObject("Ground", "GroundGen", 0)
ground.worldPosition = center.worldPosition
own["groundList"].append(ground)
for obj in own["groundList"]:
if obj.worldPosition.y <= center.worldPosition.y - 15.0: #remove obj when its not on screen anymore
own["groundList"].remove(obj)
obj.endObject()
if obj.worldPosition.y <= center.worldPosition.y and len(own["groundList"]) < 2: #add a new ground when another one reaches the center
newGround = scene.addObject("Ground", "GroundGen", 0)
own["groundList"].append(newGround)
Alright, it works and spawns the ground, but sometimes there’s a gap between two planes, sometimes there’s not, like there’s some kind of offset. I don’t understamd why this happens.
EDIT: I am just going to model the planes with an unnecessary edge which will clip through.
OK, after some work, I managed to make my player stay always in the center and move the ground instead to create the illusion of movement, but simple moving-or-stopped motion, accounting for the player’s rotation. However, I’m stuck with how I could make acceleration.
My current code:
import bge, math
cont = bge.logic.getCurrentController()
scene = bge.logic.getCurrentScene()
player = cont.owner
w = cont.sensors["w"]
s = cont.sensors["s"]
a = cont.sensors["a"]
d = cont.sensors["d"]
speedLimit = 0.5
accel = 0.001
brake = 0.01
if "vel" not in player:
player["vel"] = 0.1
angleZ = player.localOrientation.to_euler()[2]
#player rotation
if a.positive:
player.applyRotation([0.0, 0.0, 0.05], True)
if d.positive:
player.applyRotation([0.0, 0.0, -0.05], True)
#ground control
for ground in scene.objects:
if not "player" in ground: #player, camera, etc. have property "player", the rest do not
if w.positive:
x, y = (math.sin(angleZ) * player["vel"], math.cos(angleZ) * -player["vel"])
ground.applyMovement([x, y, 0.0], False)
if s.positive:
x, y = (math.sin(angleZ) * player["vel"], math.cos(angleZ) * player["vel"])
ground.applyMovement([-x, y, 0.0], False)
I made a (short) video on how it works:
I have seen acceleration with Motion actuators, but I can’t do that here as the new grounds will be added and old ones will be deleted.
But there is a new problem, which is a difference between two ground planes. It is not a “glitch”, but it should not happen.
My current code (with acceleration):
import bge, math
cont = bge.logic.getCurrentController()
scene = bge.logic.getCurrentScene()
player = cont.owner
w = cont.sensors["w"]
s = cont.sensors["s"]
a = cont.sensors["a"]
d = cont.sensors["d"]
speedLimit = 0.5
accel = 0.001
brake = 0.01
if "vel" not in player:
player["vel"] = 0.1
angleZ = player.localOrientation.to_euler()[2]
#player rotation
if a.positive:
if s.positive:
player.applyRotation([0.0, 0.0, -0.05], True)
else:
player.applyRotation([0.0, 0.0, 0.05], True)
if d.positive:
if s.positive:
player.applyRotation([0.0, 0.0, 0.05], True)
else:
player.applyRotation([0.0, 0.0, -0.05], True)
#ground control
for ground in scene.objects:
if not "player" in ground: #player, camera, etc. have property "player", the rest do not
if w.positive:
if player["vel"] <= speedLimit:
player["vel"] += accel
else:
player["vel"] = speedLimit
x, y = (math.sin(angleZ) * player["vel"], math.cos(angleZ) * -player["vel"])
elif s.positive:
if player["vel"] <= speedLimit:
player["vel"] += accel
else:
player["vel"] = speedLimit
x, y = (math.sin(angleZ) * -player["vel"], math.cos(angleZ) * player["vel"])
else:
player["vel"] = 0.0
x, y = (0.0, 0.0)
ground.applyMovement([x, y, 0.0], False)