代做Homework #6 : Continuous Worlds帮做C/C++编程

- 首页 >> OS编程

Homework #6 : Continuous Worlds

Upgrading movement, collisions, and performance as we leave grids behind

While a storied and successful approach (surviving today in games such as Civ 5 -left), grid-based scenes don’t represent the vast majority of digital worlds. We will need to leave behind the simple collision detection and movement logic of previous homeworks to embrace a more continuous approach to our worlds (right).

Pitch

Homework #6 : Continuous Worlds introduces students to a handful of additional 2D concepts, such as camera zoom, precise / continuous collisions, basic animation, smooth movement, and performance improvements as  we distance ourselves from the grid-based scene structure that has thus-far defi ned our engines.

Purpose

This assignment will--

Upgrade our scenes from a grid-based approach to a continuous approach (movement / collisions).

Introduce additional rendering features such as camera zoom levels.

Introduce basic math-based actor animation.

Introduce the concept of an Input Manager.

Introduce the concept of customizable collision volumes and AABB collision checking.

Require a more sophisticated consideration of rendering / collision detection performance.

Tasks

Study the Autograder and Assignment Submission Process

● Autograder General Guide

○ Windows / Visual Studio Guide

○ OSX / XCode Guide

○ Make Guide

Test-Driven Development

Each of the following test suites has a particular focus, and requires the implementation of particular features. You are recommended to clear all test cases in a given suite before proceeding to the next. If you break an older feature or introduce a bug, you may rely on older test suites to warn you of such regressions

(You may read about test-driven development, and why it features heavily in industry, here).

Test Suite #0 : Camera Zoom

This suite contains basic tests exercising your engine’s ability to provide zoom-related rendering functionality. Zoom can allow designers to better present their scenes to players while striking a cinematic tone.

1. rendering.config may now contain a property (double data type) called zoom_factor

a. When not defined, assume zoom_factor is 1

b. Utilize the SDL_RenderSetScale() function to scale all actors in a scene.

i. 2.0 means double their size.

ii. 0.5 means half their size (allowing us to show more actors with less visual noise).

c. UI elements (health icon, text, etc) must not be impacted by zoom_factor.

2. When a zoom occurs, it must maintain the rendering positions of all actors in the scene.

a. For example, a zoom of 0.5 should result in something like this, rather than this.

b. Warning : Avoid off-by-one-pixel errors. When calculating the x and y values of your final SDL_Rect (destination rect) for each actor, please wrap your entire calculation in std::round() and then cast this result via static_cast().

Test Suite #1 : Continuous Movement

This suite contains basic tests exercising your engine’s ability to support continuous movement of actors in response to (ideally) a convenient InputManager system.

Style. Suggestions

● As discussed in class, consider creating an Input.h/.cpp that provides convenient APIs.

○ Input::GetKey(), Input::GetKeyDown(), Input::GetKeyUp(), etc

○ Here’s a sample .h file you might consider starting with.

Tasks

1. For every frame. the player holds down a direction, they will move 0.02 scene units in that direction.

a. (ie, move them (0.02) scene units in response to arrow keys and WASD).

b. Note : If you’ve been representing actor positions and/or velocities via glm::ivec2 or some integer type, please switch to a fractional type (I recommend glm::vec2)

c. Note : Please normalize your movement vector.

i. ie, moving diagonally should not achieve greater speed than moving horizontally.

ii. Consider using glm::normalize()

1. (but be careful not to call it on the zero (0,0) vector)

2. If a player_movement_speed value is configured in game.config…

a. Travel this distance for every frame. a directional key (including WASD) is held down.

b. The default value should be considered to be 0.02

3. NPC actors should now update / move according to their vel_x and vel_y values every frame.

a. (recall that previously, they updated every 60th frame)

4. Upgrade your render ordering

a. Render ordering is still based on y position unless the render_order is specified.

b. If there are still ties, break them with actor_id

Test Suite #2 : Camera Easing

This suite contains basic tests exercising your engine’s ability to smoothly move the camera, providing improved cinematic style.

1. Thus far, we have made the camera instantaneously “jump” to the position of the player each frame.

a. (“position” here includes the cam_offset property if it is configured).

2. rendering.config may now contain a cam_ease_factor float property. If so…

a. When not defined, assume cam_ease_factor is 1

b. Every frame, after updating all actors, update the camera’s location with a smooth ease.

i. Jump cam_ease_factor of the way from cam’s current position to the player pos.

ii. Consider using new_cam_pos = glm::mix(current_cam_pos, player_current_pos, cam_ease_factor);

c. Example when cam_ease_factor is 0.05f

Test Suite #3 : Animation

This suite contains basic tests exercising your engine’s ability to support basic sprite-based animation, bringing personality and charm to a game’s actors.

1. If x_scale_actor_flipping_on_movement exists in rendering.config and is true…

a. The x component of the actor’s scale changes based on an actor’s intent to move.

i. If the actor attempts to move east, the x component should become positive (regardless of its original value).

ii. If the actor attempts to move west, the x component should become negative (regardless of its original value.

b. This results in actors looking in the direction they are moving– a charismatic result.

2. In addition to a view_image property, actors may have a view_image_back configured.

a. When the actor moves upwards, this image shows. It reverts back upon moving downwards.

b. This results in actors facing away from the camera when walking away from it.

c. Note: Do not reset the actor’s image or orientation when the actor stops moving

d. Note: Only calculate the pivot point with respect to view_image not other images.

3. If an actor has a movement_bounce_enabled property, and it is true…

a. When moving, the final rendering position of the actor will be offset (in pixels) by (0,-abs(sin(current_frame. * 0.15)) * 10.0)

b. Consider using glm::abs(), glm::sin(), and Helper::GetFrameNumber()

c. The result is a South Park-style. hopping animation that brings even singular frames to life.

Test Suite #4 : Continuous Collision and Damage

This suite contains basic tests exercising your engine’s ability to support customizable collision volumes.

1. Up to now, collisions have used the tile-based approach from previous homeworks. This is no longer suitable for us as we move away from grids and into a continuous world.

a. The blocking actor property no longer exists.

2. Two new actor properties are now available. If both are configured, the actor is considered “blocking”.

a. box_collider_width : Determines the width of the collider box in scene units (float)

b. box_collider_height : Determines the height of the collider box in scene units (float)

c. Note: The colliders are centered at the actor’s position, and thus your collision implementation must compute the extents of the collider (i.e. the top, left, right, and bottom)

d. Example– if the player actor does not have these properties configured, no collision is possible

e. Note : NPCs may now collide with the player (and reverse) if player has a collider configured.

3. If an actor attempts to move, and this movement makes their collider intersect another collider…

a. Reset movement (ie, don’t move this frame– the actor has been blocked).

i. If the actor is an npc and has a velocity, invert that velocity.

b. Note : two colliders that share a border exactly are not considered colliding / overlapping.

4. If the player actor collides with an actor holding a contact_dialogue then process any associated commands (but don’t render the dialogue text).

a. (The text would otherwise only be visible for one frame. Nasty.).

5. When an actor collides with another actor, both actors should immediately “know about” that collision happening and respond to it when it becomes their turn to update.

a. IE, if an npc walks into the player actor when the player isn’t moving, the player actor should still have contact dialogue triggered sometime that frame.

b. IE, if one moving npc walks into another moving npc, both should not move that frame. and both should invert their velocities.

i. Recommendation : Keep a “colliding_actors_this_frame” unordered_map and when you detect a collision, add yourself to the other actor’s container and add the other actor to yours. Make decisions based on the contents of this container before clearing it at the end of the frame.

6. What to do about the nearby_dialogue property?

a. A “trigger” (a collision-less collider) may be configured just like the above box collider.

b. If the player actor’s box trigger overlaps with another actor’s box trigger…

i. Process the other actor’s nearby_dialogue (commands) and render the text too.

7. Similar to the box_collider, an actor’s box_trigger may be customized--

a. box_trigger_width : Determines the width of the trigger box in scene units (float)

b. box_trigger_height : Determines the height of the trigger box in scene units (float)

c. If one or both properties are missing, no trigger collisions may occur.

8. If the player actor’s box collider overlaps with another actor’s trigger, and that actor has nearby_dialogue then process its associated commands (and do render this dialogue).

9. The transform_scale_x and transform_scale_y properties impact collider / trigger sizes.

10. A new property, view_image_damage, may be configured on a player actor.

a. When available, this sprite will be rendered for 30 frames upon receiving damage.

11. A new property, view_image_attack, may be configured on a non-player actor.

a. When available, this sprite will be rendered for 30 frames upon dealing damage to the player.

Test Suite #5 : Gameplay Sound Effects

This suite contains basic tests exercising your engine’s ability to play gameplay-related sound effects using dedicated sfx channels. Like other gameplay-related features in this assignment, we will seek to externalize (move out of c++) these features soon.

Style. Suggestions

● A dedicated file / system for managing audio / caching / initialization may be useful here.

○ The staff solution uses a pleasant AudioDB class to make playing audio easy anywhere.

1. To introduce new sfx we need to use audio channels other than 0 (already used for music / BGM).

a. 8 channels are valid by default. Increase channels to 50 via

Mix_AllocateChannels498()

i. (Many channels reduces our odds of having a sound cut off when another one plays)

ii. (Mix_OpenAudio has a channels param, but this refers to mono vs stereo)

2. A new property, score_sfx, may be configured in game.config

a. Played on the frame. in which the player’s score increases.

b. Channel : 1

3. A new property, damage_sfx, may be configured on the player actor.

a. Played on the frame. in which the player actor takes damage (no looping).

b. Channel : (current_frame) % 48 + 2

i. (the +2 prevents us from clobbering channel 0 or 1)

4. A new property, step_sfx, may be configured on the player actor.

a. This file will play on (without looping) on every 20th frame. if the actor is moving.

i. (use Helper::GetFrameNumber() % 20 == 0 to perform. the check)

b. Channel : (current_frame) % 48 + 2

5. A new property, nearby_dialogue_sfx, may be configured on an npc actor.

a. Played on the first frame. in which nearby_dialogue is processed (no looping).

i. (do not repeat the sound if the nearby_dialogue is triggered again).

b. Channel : (current_frame) % 48 + 2

Test Suite #6 : Integration and Performance Tests

This suite contains large, advanced tests that stress your engine’s correctness and performance.

Notes on Performance

● We made heavy use of Visual Studio performance profiling to determine opportunities for optimization.

● The single most critical performance consideration in this assignment relates to collision detection.

○ How can we identify overlapping actors without resorting to an O(n²) solution?

■ (ie, we don’t want to check every other actor to determine if one actor is colliding).

○ The staff solution employs a region-based spatial hashing approach.

■ IE, don’t check every actor. Just check actors in the same small “region” as you.

■ Hint : The smaller the regions are, the fewer actors we need to check for collisions.

● Q : How large should the regions be?

● Hint : Actors do not have a way of changing their collider / trigger size or scale.

○ (in this homework, that is…)

○ (constraints like this make engines less general, but enable high speed).

○ Hint : Colliders and Triggers are two different categories of collision.

■ Triggers tend to be much larger than colliders (the latter typically aimed at matching the visuals of a character, while the former surrounds a character to initiate things like dialogue).

○ The staff solution only ever modifies the spatial hashing structure when actors move between regions, and only adds/removes actors from those regions

● The staff solution engages in significant caching, trading memory for speed.

○ When rendering text, all SDL_Texture objects are cached and re-used once created.

○ When loading images, all SDL_Texture objects are cached and re-used once created.

○ When loading audio, all Mix_Chunk objects are cached and re-used once created.

● The staff solution refrains from rendering actors that are not visible to the camera.

● The staff solution refrains from sorting things that don’t need sorting.

Reflections

While you wait for the autograder to check your work and email your results, consider the following ideas–

● Four weeks into your engine– the same codebase week-after-week– how do you feel about it? Do parts feel messy and “fragile”? Do you feel parts are well-written and easy to reason about / extend?

● In this assignment the engine does not allow actors to resize their collider / trigger boxes, nor does it allow actors to be created during a scene. Constraints like these limit the expressiveness of an engine. What are the benefits?

● Can you imagine making a full game with your engine in its current state? If not, what is missing? What functionality would you like to add next?






站长地图