1 decade ago by bitmapshades
I have a basement garage level I'm building where I want the player to enter or exit a cop car and drive it around a city district. I'd also like the same entity to be controlled by the game engine so it can be used in on rails car chase sequences.
What is the most effective way to control the turning circle based on the speed the car is travelling?
How can I make the car skid to the side when shunted by an enemy vehicle but still keep it's velocity?
Here's a snippet from car.js:
What is the most effective way to control the turning circle based on the speed the car is travelling?
How can I make the car skid to the side when shunted by an enemy vehicle but still keep it's velocity?
Here's a snippet from car.js:
// Car Entity v0.2
EntityCar = ig.Entity.extend({
// Entity properties
collides: ig.Entity.COLLIDES.ACTIVE,
type: ig.Entity.TYPE.A, //friendly faction
checkAgainst: ig.Entity.TYPE.B, //enemy faction
// 2D top down driving model
size: {x: 80, y: 40}, // twice the width of the player character
health: 100,
speed: 0, // car is parked by default
maxvel: 120, // max velocity
friction: 0.2,
accel: 1, // acceleration
angle: 0, // facing angle
steering: 0,
maxSteerLeft: -90,
maxSteerRight: 90,
mode: 'stop', // default mode
// Load animation sheet
animSheet: new ig.AnimationSheet( 'media/cop-car.png', 80, 40 ),
init: function(x, y, settings) {
this.parent(x, y, settings);
// Add animations for cop car
// Headlights and sirens will be separate entities
this.addAnim('idle', 1, [0] );
this.addAnim('accelerate', 0.3, [1,2,3] );
this.addAnim('brake', 0.3, [4,5,6] );
this.addAnim('opendoor', 0.5, [4,5,6] );
this.addAnim('closedoor', 0.5, [7,8,9] );
},
debug: function(){
ig.log('Car mode: ' + this.mode);
ig.log('Car speed: ' + this.speed);
ig.log('Car angle: ' + this.angle);
ig.log('Car pos x: ' + this.pos.x + ' Car pos y: ' + this.pos.y);
},
check: function(other) {
// Collision with fixed entities here
// Collision with hazard entities here
},
enterCar: function(){
if(ig.game.player){
ig.game.player.currentAnim = null;
ig.game.player.collides = ig.Entity.COLLIDES.NEVER;
ig.game.player.checkAgainst = ig.Entity.TYPE.NONE;
}
},
exitCar: function() {
if(ig.game.player){
ig.game.player.collides = ig.Entity.COLLIDES.ACTIVE;
ig.game.player.checkAgainst = ig.Entity.TYPE.B;
ig.game.player.currentAnim = ig.game.player.anims.idle;
ig.game.player.pos.x = this.pos.x; // needs offset values to position the player next to the driver's door
ig.game.player.pos.y = this.pos.y;
}
},
// Snap angle to specified target, used in cutscenes
setAngle: function(target) {
this.angle = this.angleTo(target);
this.currentAnim.angle = this.angle;
},
// Accelerate
accelerate: function() {
if(this.speed < this.maxvel){
this.speed += this.accel;
}
this.currentAnim = this.anims.accelerate;
},
// Brake
brake: function() {
if(this.speed > 0 ){
this.speed -= this.accel;
}
this.currentAnim = this.anims.brake;
},
// Steering
turnLeft: function(amount) {
this.angle -= amount;
},
turnRight: function(amount) {
this.angle += amount;
},
update: function() {
this.debug(); //trace car physics
// Set driving mode when player has activated the car
if(ig.game.player) {
if(ig.input.pressed('use')){
if(this.distanceTo(ig.game.player) < 20 && this.mode == 'stop'){
this.currentAnim = this.anims.opendoor;
this.mode = 'driving';
this.enterCar(); //Hide the player and ignore collisions
}
else if(this.mode == 'driving'){
this.currentAnim = this.anims.opendoor;
this.mode = 'stop';
this.exitCar(); //Show the player and enable collisions
}
}
}
// Player driving mode
if(ig.game.state == 'play' && this.mode == 'driving') {
// Accelerator
if(ig.input.pressed('accelerate') ){
this.accelerate();
}
else if(ig.input.released('accelerate') ){
this.speed *= this.friction;
}
// Brake
if(ig.input.pressed('brake')) {
this.brake();
}
// Steering
if(ig.input.pressed('turnleft')) {
// We need to limit the steering so the car doesn't spin around on the spot
if(this.steering >= this.maxSteerLeft){
this.steering -= (this.speed / 4); // steering should be a fraction of the current speed
}
this.turnLeft(this.steering);
}
else if(ig.input.pressed('turnright') ){
if(this.steering <= this.maxSteerRight){
this.steering += (this.speed / 4);
}
this.turnLeft(this.steering);
}
}
// Stop the car or when player exits the car
if(ig.game.state == 'play' && this.mode == 'stop'){
this.speed = 0;
this.steering = 0;
}
// apply velocity by angle and speed
this.vel.x = cos(this.angle) * this.speed;
this.vel.y = sin(this.angle) * this.speed;
this.currentAnim = this.anims.idle;
this.currentAnim.angle = this.angle;
// Update display
this.parent();
}
});
