User Tools

Site Tools


haas:spring2024:comporg:projects:mag1

Corning Community College

CSCS2650 Computer Organization

PROJECT: Make A Game (MAG1)

OBJECTIVE

Commencing on a multi-week effort to develop a game entirely in assembly.

EDIT

You will want to go here to edit and fill in the various sections of the document:

MAGx

Infinite Runner Game

An infinite runner involves a character moving along an infinitely long stage overcoming obstacles placed along the path. That's the foundation. Other additions can include an increasing speed, procedurally generated obstacles, etc.

Parallax Scrolling Background

A parallax background involves multiple layers scrolling along at different speeds to simulate depth. Layers farther back in the scene move slower than those closer to the camera.

Data Needed for Parallax

Each layer needs at least a X Position and Speed variables. On each frame, the X Position is subtracted by the Speed, so that the layer moves at a constant rate. Once the layer moves off-screen, increment its' X Position by the width of the layer asset so it's back on-screen and the scrolling effect doesn't have any cuts. (For simplicity, each layer asset is the width of the screen size.)

Substituting Different Assets in a Layer

Sometimes you want to include alternate variants of a layer asset for added visual flair. This'll require an array for however many slots you want within the layer (For this example, we'll go six with the last slot being the variant). We'll use a type variable to determine which asset variant to select (a boolean). When rendering the layer, it looks at the type to determine the texture variant to select.

Player Physics and Animations
Player Movement

Since the parallax background already gives the impression of horizontal speed, the player does not actually need to move across the X-axis of the screen. This value can remain fixed throughout all gameplay scenarios.

The player will be able to perform two actions while automatically running along: Sliding and Jumping with the A and B buttons respectively. These two actions are mutually exclusive.

Sliding is simple. When the B button is held, the player will slide along the ground indefinitely. In this state, the player is half as tall and can duck under obstacles. Jumping is more complicated.

Variable Jump Height

When the Player jumps, they have some control over how high the jump is depending on how long the A button is held. To code such a feature, you'll need variables for the Player's position, speed, and acceleration. Each frame, the acceleration is added to the speed, and then the speed is added onto the position to create an arcing motion.

The instant the button is pressed, the speed and acceleration of the player is set to be negative (negative is upwards). If the A button is released while the player is rising, the acceleration will decrease significantly (ex. from -1 to -3), which will allow the Player to go through the jump arc at a faster rate. As soon as the player starts falling back towards the ground, the acceleration is fixed no matter the button state so that the illusion of gravity remains consistent.

Animation Control

Since the player has three different states (running, jumping, and sliding), there will be 3 different animation states.

While sliding, the player will be shown as sliding across the ground in a single pose.

While jumping, the player will have two different visuals for jumping up and falling down. The asset that gets drawn will be dependent on the player's speed value. (If speed is negative, the player jump sprite is shown, if positive, the falling sprite).

While running, the player will cycle between four different running sprites. A flag variable will be used to note which sprite should get displayed (0-3). Every 7 frames, the flag will get incremented and then modulated by 4. This can be achieved by using the FrameCounter that's built into Vircon32.

The running animation is the default one that gets played, and will be overwritten when the player either jumps or slides.

Obstacle Infrastructure and Generation

Every good runner needs to have obstacles to avoid! For this runner, we'll have two building blocks: A block and a spike.

Our obstacles will be controlled by an integer flag. A zero means no obstacle is spawned, and any number higher corresponds with an obstacle pattern. This flag can be triggered by the console clock, RNG, or whatever.

When an obstacle is spawned (the flag is turned from 0 to a number), A variable we'll call “Obstacle X” is set to be a little over 640. The Obstacle X variable is a reference position in which each building block of the obstacle pattern will be positioned relative to. We only need to set the X as the Y will remain constant at ground level. Obstacle X will move left at the same rate as the background layer until it reaches at least -640. At this point, the Obstacle flag will be set to zero again, and a new pattern can be spawned.

Each obstacle pattern will essentially be an array/list for each building element. Each element will have three variables:

  1. Object type ( 0=Block, 1=Spike )
  2. Position X
  3. Position Y

Again, the Position data will be updated relative to the Obstacle X reference point. Additionally, a size variable will be kept in the stack so that we know how many elements reside within each obstacle pattern.

Obstacle Collision and Rendering

The processes for both collision checks and rendering are relatively the same. First, we check the Obstacle flag to see which pattern is currently spawned, and then grab the size variable associated with it. Secondly, we use that size variable to for-loop through each element in the obstacle to then either run collision checks on it, or render it.

For Collision, we check if the element is either a Block or a Spike using the Object Type variable. If it's a block, we run checks to see if the Player is on top of it, so that the Player can run and jump along it, or if the Player is in it to trigger a game over. For Spikes, there are two boxes inside it that if the player enters also triggers a game over.

For Rendering, the Object Type check is the same to select the right texture region, which gets printed at that position. Relatively simple.

 

SUBMISSION

To be successful in this project, the following criteria (or their equivalent) must be met:

  • Project must be submit on time, by the deadline.
    • Late submissions will lose 33% credit per day, with the submission window closing on the 3rd day following the deadline.
  • Executed programs must display in a manner similar to provided output
    • output formatted, where applicable, must match that of project requirements
  • Processing must be correct based on input given and output requested
  • Output, if applicable, must be correct based on values input
  • Code must be nicely and consistently indented
  • Code must be consistently written, to strive for readability from having a consistent style throughout
  • Code must be commented
    • Any “to be implemented” comments MUST be removed
      • these “to be implemented” comments, if still present at evaluation time, will result in points being deducted.
      • Sufficient comments explaining the point of provided logic MUST be present
  • No global variables (without instructor approval), no goto statements, no calling of main()!
  • Track/version the source code in your lab46 semester repository
  • Submit a copy of your source code to me using the submit tool by the deadline.

Submit Tool Usage

Let's say you have completed work on the project, and are ready to submit, you would do the following:

lab46:~/src/SEMESTER/DESIG/PROJECT$ submit DESIG PROJECT file1 file2 file3 ... fileN

You should get some sort of confirmation indicating successful submission if all went according to plan. If not, check for typos and or locational mismatches.

RUBRIC

I'll be evaluating the project based on the following criteria:

78:mag1:final tally of results (78/78)
*:mag1:documentation and code progress [78/78]

Pertaining to the collaborative authoring of project documentation

  • each class member is to participate in the contribution of relevant information and formatting of the documentation
    • minimal member contributions consist of:
      • near the class average edits (a value of at least four productive edits)
      • near the average class content change average (a value of at least 1024 bytes (absolute value of data content change))
      • near the class content contribution average (a value of at least 1kiB)
      • no zero-sum commits (adding in one commit then later removing in its entirety for the sake of satisfying edit requirements)
    • adding and formatting data in an organized fashion, aiming to create an informative and readable document that anyone in the class can reference
    • content contributions will be factored into a documentation coefficient, a value multiplied against your actual project submission to influence the end result:
      • no contributions, co-efficient is 0.50
      • less than minimum contributions is 0.75
      • met minimum contribution threshold is 1.00

Additionally

  • Solutions not abiding by spirit of project will be subject to a 50% overall deduction
  • Solutions not utilizing descriptive why and how comments will be subject to a 25% overall deduction
  • Solutions not utilizing indentation to promote scope and clarity or otherwise maintaining consistency in code style and presentation will be subject to a 25% overall deduction
  • Solutions not organized and easy to read (assume a terminal at least 90 characters wide, 40 characters tall) are subject to a 25% overall deduction
haas/spring2024/comporg/projects/mag1.txt · Last modified: 2023/10/31 10:01 by 127.0.0.1