A recent study of C # development of WPF/Silverlight animation and game series in the left-hand dark blue
Http://www.cnblogs.com/alamiye010/archive/2009/06/17/1505346.html
The notes are as follows:
1. The movement of a character is divided into two parts: the movement of the centroid and the animation of the character's own movement. This reminds me of the last course of my senior year, "Rigid Body Mechanics".
2. for image, in WPF:
Spirit. Source = new bitmapimage (New uri (@ "player \" + Count + ". PNG", urikind. Relative ));
In Silverlight, it is:
Spirit. Source = new bitmapimage (New uri (@ "player/" + Count + ". PNG", urikind. Relative ));
3. *Algorithm
Finally, I want to understand why the character always goes first on the diagonal line of the square and then on the horizontal side. It turns out to be an implementation method of the * algorithm.
4. To save/load, use memento
To implement record, you need to implement command and store the operation to be stored as command to the set.
5. Copy map is definitely a good thing, but it must be implemented in conjunction with the map editor.
6. Use the copy map in SL.
ObtainSpecify a pixel of an imageThe color of the vertex.
Private void img3_mousemove (Object sender, mouseeventargs E)
{
Writeablebitmap bitmap = new writeablebitmap (img3, null );
Int color = bitmap. pixels [(INT) E. getposition (img3). y * (INT) img3.actualwidth + (INT) E. getposition (img3). x];
// Convert an integer to a byte array
Byte [] bytes = bitconverter. getbytes (color );
// Convert byte arrays to colors (Bytes [3]-A, bytes [2]-R, bytes [1]-G, bytes [0]-B)
LBL. Text = color. fromargb (Bytes [3], bytes [2], bytes [1], bytes [0]). tostring ();
}
7. In WPF, system. Drawing. Point is new system. Windows. Point in SL.
8. Silverlight skills: how to get the mouse wheel event and how to judge and obtain the combination key
9. It seems that the resource corresponds to.../, but it can only be clip.
The/images corresponding to content is used for WB
10. x = left + centerx
Finally, the axis of the monster has been completed. Change obj. centery in the formula of the static object to OBJ. Y-obj. centery. Of course, centerx is like a method.
11. added an ismoving to control the change of the coordinates calculated every second to the end of each click.
12. It seems that dispatchertimer priority cannot be controlled in SL.
13. Updated the silverlightcontrol20_mousemove method of the genie pick-up method. The for loop of the original method is too many times.
14. Change the vlift array to vlift and vlifemax attributes.
15. dynamic obstacle Modification
1) Change martrix to fixedobstruction and add varyobstruction.
2) Change the initmartrix method to initobstruction and add the statement at the end:
Varyobstruction = fixedobstruction. Clone () as byte [,];
3) change the path search algorithm astarmoveto, left-click the carrier_mouseleftbuttondown method, and check the variable fixedobstruction in the willcollide method of the surrounding obstacle to varyobstruction.
4) modify the willcollide method to expand the obstacle range (introduce holdwidth and holdheight)
5) create a background auxiliary thread
// Set the background threadBackgroundworker =NewBackgroundworker(); Backgroundworker. dowork + =NewDoworkeventhandler(Backworker_dowork );// Sets the game form secondary TimerDispatchertimerAuxiliarythread =NewDispatchertimer(); Auxiliarythread. Tick + =NewEventhandler(Auxiliarythread_tick); auxiliarythread. interval =Timespan. Frommilliseconds (1000); auxiliarythread. Start ();
16. Upgrade Chapter 28 to change the image path
Finally, I felt that so many functions in SL were prepared for game development.
17. Implement attack actions
1) added several attributes to spirit. 5-dimensional basic attributes and 20-length array merging Parameters
2) Modify spirit:
The timer_tick thread method is modified. when the action is attrack, the newly added doinjure method is called.
Added the lockobject attribute to get or set the target genie object to be locked.
Added the attackrange attribute to get or set the physical attack range (distance). Currently, it is only used by leader.
Added the effectiveframe attribute to obtain or set the sequence number of the frames that each action produces.
The changeaction method adds the attack action. The speed is interval and needs to be reconstructed again.
3) modify the main form
The initfaceplate method is unified (originally two). Therefore, four attributes (facesign, pkmode, vsname, and vlevel) are added to qxroleface.
Extended isopposition Method
Added the monitoring object: String watchobj = NULL; and modified the updateobjectfaceplate method accordingly.
The updateobjectfaceplate and updateleaderfaceplate methods have been modified. Therefore, four attributes are added to qxroleface, which are not cleaned up, but are basically enough.
Added the willattack method to determine whether to initiate an attack to the locked object.
Modify the refreshobstruction method to refreshobstructionandfaceplate, execute the updateobjectfaceplate and updateleaderfaceplate methods in it, finally determine whether it is in the attack range, and set the lockobject object
Lockobject and watchobj are two things. They are designed to be redundant. They delete watchobj and upgrade lockobject to a qxspirit object.
Add the spiritedge method to obtain the actual soles of the feet of the attacker based on the attacker's orientation (used to identify attack paths)
In the auxiliarythread_tick thread method, hereCodeIf there is a problem, we should not refresh the main attack object and start searching here (this is done in compositiontarget)
Reconstructed silverlightcontrol20_mousemove. The original code is not easy to debug.
Expanded pathfinding Logic
Considering that mousemove is executed before mouseleftdown, you can directly use the hitspritelist set in the mouseleftdown method without performing a hit test again.
In the mouseleftdown method, if you click yourself, ignore it directly.
Strangely, in the window ctor, the width of the window is not set yet.
This is done, but the second attack will remain unchanged. Remember this bug and handle it later.
18. 28_1
Add new features
1) Disable right-click
2) qxdecoration is amazing. The special effects, soles of the feet, and mouse clicks correspond to 2, 6, and 1 under image/item respectively.
Clicking the Halo with the mouse is a non-moving obstacle and must be moved together in allmove.
3) Background Music
4) set the animation for damage to the top of the spirit head:-100 or miss
Refactor the Old Code
1) Abstract super. getimage (@ "/images/cursors/0.png") to the getcursor method.
2) use point animation instead of double animation.
3) For convenience, rootcanvas and parentcanvas are added to spirit. The former is the current root canvas, and the latter is the father canvas.
4) The willcollide boundary control is modified because the values of holdwidth and holdheight are added.
5) set the qxgame_silverlight3.dll compilation action to none.
6) The allmove method is re-expanded to support the mouse cursor
7) The willcollide method should be retried. For example, if spirit enters the vicinity of the monster obstacle and then moves to another place, it will be executed in the carrier_mouseleftbuttondown method.
Else if (! Willcollide ())
In this sentence, we will find that there are "obstacles" around it, so that it will not move. Replace it:
// Point to the place where it is not an obstacle to move
If (varyobstruction [(INT) (p. x/gridsizex), (INT) (p. Y/gridsizey)]! = 0)
{
......
}
.
8) spirit seems to always be in front of monster. This is because I didn't set the zindex of the monster in the initmonster method.
9) When leader or monster is bleeding, the value-100 or miss is displayed on the top of the head.
Since this dynamic text was originally displayed in the main form, it needs to be processed in the allmove method as spirit moves.
Now I put it in qxspirit and changed its location:
X = 0,
Y = 0-math. Abs (spirit. descriptiontop), // vertical top processing
That's all.
10) fixed the bug of attacking the monster Jia han but the monster Guo Xiaoying's blood loss.
11) modify the compositiontarget_rendering method of the main form. When the main form is in the attack range, no loop is performed. Set ismoving to false.
// End the loop
Ismoving = false;
19. Add the death effect, Project No. 29
Monsters:
1) In the changeaction method, add a branch
CaseActions. Death: timer. interval =Timespan. Frommilliseconds (300); currentstartframe = eachactionframerange [0] + eachactionframerange [1] + eachactionframerange [2] + eachactionframerange [3]; currentendframe = eachactionframerange [0] + eachactionframerange [1] + eachactionframerange [2] + eachactionframerange [3] + eachactionframerange [4]-1; oldaction =Actions. Death;Break;
2) Add the battlehandle method to the doinjure Method for post-war processing.
3) in spirit, add two death tags:
BoolIsdeath =False;IntDeathdelay = 0;
In order to prevent non-synchronization with the main thread, the timer_tick method of the spirit should be judged at the beginning. Once it crashes, it will save its body. After six cycles, re-cremation (execute the removeobject method ). There will be enough delay in this period, and no null exception event will occur.
If(Isdeath) {deathdelay + = 1;If(Deathdelay = 6 ){Super. Removeobject (This,True);}Return;}
At the same time, add the branch in the timer_tick method of spirit and set the isdeath variable -- dead:
Case actions. Death:
Isdeath = true;
Break;
4) dark blue right hand setting dead operation, that is, Spirit. Action = actions. Stop; I cannot find
I set it directly in the battlehandle method. In this way, the spirit can be stopped, rather than sending a zombie.
20. Let the monster go up. Project No. 29_1
1) create a storyboard dictionary for all spirit in super
Super can't do anything. Abstract storyboardregfactory.
2) In refreshobstructionandfaceplate, abstract the refreshing dynamic obstacle method into updatemonsters, and add the logic in it to detect the monster seekrange and lock the monster's lockobject.
3) Because monsters also have attackrange, the leader does not need to have foot obstacles. Both holdwifth and holdheight are 0.
4) methods for adding the spirit parameter: willcollide, astarmoveto, and moveTo
Abstract The arrivetarget and allactive methods.
5) upgrade unitmovecost to the vrunspeed attribute of spirit. Leader is 70, and monsters are read from XML.
6) Killing the monster or clicking somewhere else, the monster panel disappears and is determined in the compositiontarget_rendering and carrier_mouseleftbuttondown methods respectively.
7) The ismoving mark is no longer needed. It is not cost-effective. It is better to move the ismoving every time.
8) When a bug is found, the monster clicks the position of the corpse again after the death, and will die in carrier_mouseleftbuttondown.
If(Isefficacioussection (hitsprite [I]. efficacioussection, E. getposition (hitsprite [I])
Here, the hitsprite [I] is a dead monster and has not been cremated, so an exception will be reported. E. getposition cannot handle the body.
Therefore, the gethitsprite method is modified,
// Starting from 2, because two objects are first discoveredFor(IntI = 2; I If(Hitelements [I]IsQxspirit29_1){Qxspirit29_1OBJ = hitelements [I]AsQxspirit29_1;If(Obj. vlife! = 0) hitspritelist. Add (OBJ );}}
In this way, only the dead monsters are added to hitspritelist.
21. Project 29_2, rebuild
Add new features
1) Import experience and upgrade System
Data: Add levelup nodes to XML to add experience values to monsters
Creation: single-piece levelupexperiencesingleton
Read: Read the levelupexperiencelist array in XML.
Allocation: Set vexperience and vexperiencemax for leader
Use: add the earnexperience method to qxspirit.
Display: Update level and exp in the leader panel. Change it to experience value considering the energy value on the panel is useless.
Refactor old code
1) Split gridsize into gridsizex and gridsizey
2) The dimension settings of the fixedobstruction array are rule-based. To do this, add the getmatrixsize method.
3) qxspirit discriptiontop Initialization
Leader. descriptiontop = (leader. Body. Height-160)/2-30;
22. Cast magic in project 30
Set leader magic to 600
Activemonster
Clarify the character Action Logic
It seems that the corresponding storyboard is not removed when the monster is dead.
23. 3rd Restructures
1) Change doubleanimation to pointanimation, and then modify the iobject interface.
The Mechanism is: Once the coordinate attribute is changed, the left and top attributes of the coordinate object will be modified.
In this way, the additional settings of left and top are saved, and the automatic callback is quite good.
I am exhausted. I have changed 144 places, and I want to get rid of the X and Y key frame animations in astarmove and normalmove.
It cannot be written like this:
This. Coordinate. Y-= 3;
Because coordinate is a point, it is a struct
Leader. Coordinate = new point (x, y); this will trigger the callback function changecoordinatecallback -- use the centerx and centery of the leader to update the top and left of the leader.
Can we write it as follows:
Leader =NewQxspirit() {Name ="Leader", Type =Spirit. Leader, direction = direction, centerx = 75, centery = 110, coordinate =NewPoint(X, y ),
};
When coordinate is set, does centerx and centery already have values?
Test shows that the preceding statement is caused by coordinate =NewPoint(X, y), located after centerx = 75, centery = 110. Therefore, when the callback function changecoordinatecallback is triggered, centerx and centery already have values.
If you set coordinate =NewPoint(X, y), the position is raised to centerx = 75, centery = 110. Previously, the callback function changecoordinatecallback will trigger in centerx = 75, centery = 110, before, in this case, both centerx and centery are 0.
Similarly, I want to set zindex to centerx = 75, centery = 110, and then
Neither left nor top. zindex is required.
2) Unify the Coordinate Variables of all objects
3) Change allmove to canvas
4) refactored super, the image cache was independent, and music threw it back to the main window,
5) reschedule the iobject Interface
6) Remove the type attribute of qxspirit.
7) Complete the magic, read data from XML, calculate the magic damage, right-click and adjust the magic cast position
8) Where are static obstacles?