Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Adjustments Needed But Can't Figure Out: -Adjust the player characters response to obstacles so that lava kills the player. This means that if the player

Adjustments Needed But Can't Figure Out:

-Adjust the player characters response to obstacles so that lava "kills" the player. This means that if the player hits lava, they should restart the level: send their position to a new Vector(10,10). If the player hits lava, they probably fell into it. Start by trying to modify the moveY function.

-Adjust the players jump speed, movement speeds, and gravity to give the level a different feel. Make sure you choose settings that are still playable but interesting: for instance, you might make the player a super-jumper in a world with very strong gravity.

-How you would delay the restart and signal to the player that they have died (perhaps by changing their characters color until the restart using a different CSS class).

Current Game Code (in JavaScript):

function Level(plan) {

// Use the length of a single row to set the width of the level this.width = plan[0].length; // Use the number of rows to set the height

this.height = plan.length;

// Store the individual tiles in our own, separate array this.grid = [];

// Loop through each row in the plan, creating an array in our grid for (var y = 0; y < this.height; y++) { var line = plan[y], gridLine = [];

// Loop through each array element in the inner array for the type of the tile for (var x = 0; x < this.width; x++) { // Get the type from that character in the string. It can be 'x', '!' or ' ' // If the character is ' ', assign null.

var ch = line[x], fieldType = null; // Use if and else to handle the three cases if (ch==='@') // Create a new player at that grid position. this.player = new Player(new Vector(x, y)); else if (ch == "x") fieldType = "wall"; // Because there is a third case (space ' '), use an "else if" instead of "else" else if (ch == "!") fieldType = "lava"; else if (ch == "P") fieldType = "player";

// "Push" the fieldType, which is a string, onto the gridLine array (at the end). gridLine.push(fieldType); } // Push the entire row onto the array of rows. this.grid.push(gridLine); } }

function Vector(x, y) { this.x = x; this.y = y; }

// Vector arithmetic: v_1 + v_2 = + = Vector.prototype.plus = function(other) { return new Vector(this.x + other.x, this.y + other.y); };

// Vector arithmetic: v_1 * factor = *factor = Vector.prototype.times = function(factor) { return new Vector(this.x * factor, this.y * factor); };

// A Player has a size, speed and position. function Player(pos) { this.pos = pos.plus(new Vector(0, -0.5)); this.size = new Vector(0.8, 1.5); this.speed = new Vector(0, 0); } Player.prototype.type = "player";

// Helper function to easily create an element of a type provided // and assign it a class. function elt(name, className) { var elt = document.createElement(name); if (className) elt.className = className; return elt; }

// Main display class. We keep track of the scroll window using it. function DOMDisplay(parent, level) {

// this.wrap corresponds to a div created with class of "game" this.wrap = parent.appendChild(elt("div", "game")); this.level = level;

// In this version, we only have a static background. this.wrap.appendChild(this.drawBackground());

// Keep track of actors this.actorLayer = null;

// Update the world based on player position this.drawFrame(); }

var scale = 20;

DOMDisplay.prototype.drawBackground = function() { var table = elt("table", "background"); table.style.width = this.level.width * scale + "px";

// Assign a class to new row element directly from the string from // each tile in grid this.level.grid.forEach(function(row) { var rowElt = table.appendChild(elt("tr")); rowElt.style.height = scale + "px"; row.forEach(function(type) { rowElt.appendChild(elt("td", type)); }); }); return table; };

// Draw the player agent DOMDisplay.prototype.drawPlayer = function() { // Create a new container div for actor dom elements var wrap = elt("div");

var actor = this.level.player; var rect = wrap.appendChild(elt("div", "actor " + actor.type)); rect.style.width = actor.size.x * scale + "px"; rect.style.height = actor.size.y * scale + "px"; rect.style.left = actor.pos.x * scale + "px"; rect.style.top = actor.pos.y * scale + "px"; return wrap; };

DOMDisplay.prototype.drawFrame = function() { if (this.actorLayer) this.wrap.removeChild(this.actorLayer); this.actorLayer = this.wrap.appendChild(this.drawPlayer()); this.scrollPlayerIntoView(); };

DOMDisplay.prototype.scrollPlayerIntoView = function() { var width = this.wrap.clientWidth; var height = this.wrap.clientHeight;

// We want to keep player at least 1/3 away from side of screen var margin = width / 3;

// The viewport var left = this.wrap.scrollLeft, right = left + width; var top = this.wrap.scrollTop, bottom = top + height;

var player = this.level.player; // Change coordinates from the source to our scaled. var center = player.pos.plus(player.size.times(0.5)) .times(scale);

if (center.x < left + margin) this.wrap.scrollLeft = center.x - margin; else if (center.x > right - margin) this.wrap.scrollLeft = center.x + margin - width; if (center.y < top + margin) this.wrap.scrollTop = center.y - margin; else if (center.y > bottom - margin) this.wrap.scrollTop = center.y + margin - height; };

// Return the first obstacle found given a size and position. Level.prototype.obstacleAt = function(pos, size) { // Find the "coordinate" of the tile representing left bound var xStart = Math.floor(pos.x); // right bound var xEnd = Math.ceil(pos.x + size.x); // top bound var yStart = Math.floor(pos.y); // Bottom bound var yEnd = Math.ceil(pos.y + size.y);

// Consider the sides and top and bottom of the level as walls if (xStart < 0 || xEnd > this.width || yStart < 0 || yEnd > this.height) return "wall";

// Check each grid position starting at yStart, xStart // for a possible obstacle (non null value) for (var y = yStart; y < yEnd; y++) { for (var x = xStart; x < xEnd; x++) { var fieldType = this.grid[y][x]; if (fieldType) return fieldType; } } };

// Update simulation each step based on keys & step size Level.prototype.animate = function(step, keys) {

// Ensure each is maximum 100 milliseconds while (step > 0) { var thisStep = Math.min(step, maxStep); this.player.act(thisStep, this, keys); // Do this by looping across the step size, subtracing either the // step itself or 100 milliseconds step -= thisStep; } };

var maxStep = 0.05;

var playerXSpeed = 7;

Player.prototype.moveX = function(step, level, keys) { this.speed.x = 0; if (keys.left) this.speed.x -= playerXSpeed; if (keys.right) this.speed.x += playerXSpeed;

var motion = new Vector(this.speed.x * step, 0); // Find out where the player character will be in this frame var newPos = this.pos.plus(motion); // Find if there's an obstacle there var obstacle = level.obstacleAt(newPos, this.size);

// Move if there's not a wall there. if(obstacle!="wall") this.pos = newPos; };

var gravity = 30; var jumpSpeed = 17; var playerYSpeed = 7;

Player.prototype.moveY = function(step, level, keys) { // Accelerate player downward (always) this.speed.y += step * gravity;; var motion = new Vector(0, this.speed.y * step); var newPos = this.pos.plus(motion); var obstacle = level.obstacleAt(newPos, this.size); // The floor is also an obstacle -- only allow players to // jump if they are touching some obstacle. if (obstacle) { if (keys.up && this.speed.y > 0) this.speed.y = -jumpSpeed; else this.speed.y = 0; } else { this.pos = newPos; } };

Player.prototype.act = function(step, level, keys) { this.moveX(step, level, keys); this.moveY(step, level, keys); };

// Arrow key codes for readibility var arrowCodes = {37: "left", 38: "up", 39: "right", 40: "down"};

// Translate the codes pressed from a key event function trackKeys(codes) { var pressed = Object.create(null);

// alters the current "pressed" array which is returned from this function. // The "pressed" variable persists even after this function terminates // That is why we needed to assign it using "Object.create()" as // otherwise it would be garbage collected

function handler(event) { if (codes.hasOwnProperty(event.keyCode)) { // If the event is keydown, set down to true. Else set to false. var down = event.type == "keydown"; pressed[codes[event.keyCode]] = down; // We don't want the key press to scroll the browser window, // This stops the event from continuing to be processed event.preventDefault(); } } addEventListener("keydown", handler); addEventListener("keyup", handler); return pressed; }

// frameFunc is a function called each frame with the parameter "step" // step is the amount of time since the last call used for animation function runAnimation(frameFunc) { var lastTime = null; function frame(time) { var stop = false; if (lastTime != null) { // Set a maximum frame step of 100 milliseconds to prevent // having big jumps var timeStep = Math.min(time - lastTime, 100) / 1000; stop = frameFunc(timeStep) === false; } lastTime = time; if (!stop) requestAnimationFrame(frame); } requestAnimationFrame(frame); }

// This assigns the array that will be updated anytime the player // presses an arrow key. We can access it from anywhere. var arrows = trackKeys(arrowCodes);

// Organize a single level and begin animation function runLevel(level, Display) { var display = new Display(document.body, level);

runAnimation(function(step) { // Allow the viewer to scroll the level level.animate(step, arrows); display.drawFrame(step); }); }

function runGame(plans, Display) { function startLevel(n) { // Create a new level using the nth element of array plans // Pass in a reference to Display function, DOMDisplay (in index.html). runLevel(new Level(plans[n]), Display); } startLevel(0); }

CSS CODE:

.background { background: rgb(52, 166, 251); table-layout: fixed; border-spacing: 0; } .background td { padding: 0; } .lava { background: rgb(255, 100, 100); } .wall { background: white; }

.actor { position: absolute; } .player { background: rgb(64, 64, 64); }

.game { overflow: hidden; max-width: 600px; max-height: 450px; position: relative; }

HTML CODE:

GAME LEVELS LAYOUT:

var GAME_LEVELS = [ [" ", " ", " ", " ", " ", " ", " xxx ", " xx xx xx!xx ", " o o xx x!!!x ", " xx!xx ", " xxxxx xvx ", " xx ", " xx o o x ", " x o x ", " x xxxxx o x ", " x xxxx o x ", " x P x x xxxxx x ", " xxxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx xxxxxxx xxxxxxxxx ", " x x x x ", " x!!!x x!!!!!x ", " x!!!x x!!!!!x ", " xxxxx xxxxxxx ", " ", " "], [" x!!x xxxxxxx x!x ", " x!!x xxxx xxxx x!x ", " x!!xxxxxxxxxx xx xx x!x ", " xx!!!!!!!!!!xx xx xx x!x ", " xxxxxxxxxx!!x x o o o x!x ", " xx!x x o o xx!x ", " x!x x xxxxxxxxxxxxxxx!!x ", " xvx x x x !!!!!!!!!!!!!!xx ", " xx | | | xx xxxxxxxxxxxxxxxxxxxxx ", " xx!!!!!!!!!!!xx v ", " xxxx!!!!!xxxx ", " x x xxxxxxx xxx xxx ", " x x x x x x ", " x x x x ", " x x xx x ", " xx x x x ", " x x o o x x x x ", " xxxxxxx xxx xxx x x x x x x ", " xx xx x x x x xxxxxx x x xxxxxxxxx x ", " xx xx x o x x xx x x x x ", " P x x x x x x x x x x ", " xxx x x x x x x x xxxxx xxxxxx x ", " x x x x xx o xx x x x o x x x ", "!!!!x x!!!!!!x x!!!!!!xx xx!!!!!!!!xx x!!!!!!!!!! x = x x x ", "!!!!x x!!!!!!x x!!!!!xx xxxxxxxxxx x!!!!!!!xx! xxxxxxxxxxxxx xx o o xx ", "!!!!x x!!!!!!x x!!!!!x o xx!!!!!!xx ! xx xx ", "!!!!x x!!!!!!x x!!!!!x xx!!!!!!xx ! xxxxxxx ", "!!!!x x!!!!!!x x!!!!!xx xxxxxxxxxxxxxx!!!!!!xx ! ", "!!!!x x!!!!!!x x!!!!!!xxxxxxxxx!!!!!!!!!!!!!!!!!!xx ! ", "!!!!x x!!!!!!x x!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!xx ! "];
 if (typeof module != "undefined" && module.exports) module.exports = GAME_LEVELS;

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

DB2 Universal Database V7.1 Application Development Certification Guide

Authors: Steve Sanyal, David Martineau, Kevin Gashyna, Michael Kyprianou

1st Edition

0130913677, 978-0130913678

More Books

Students also viewed these Databases questions

Question

Define Administration and Management

Answered: 1 week ago

Question

Define organisational structure

Answered: 1 week ago

Question

Define line and staff authority

Answered: 1 week ago

Question

Define the process of communication

Answered: 1 week ago

Question

Explain the importance of effective communication

Answered: 1 week ago