{"id":736,"date":"2013-12-02T21:10:41","date_gmt":"2013-12-02T20:10:41","guid":{"rendered":"http:\/\/labalec.fr\/erwan\/?p=736"},"modified":"2013-12-02T21:11:13","modified_gmt":"2013-12-02T20:11:13","slug":"vb-net-and-xna-article-17-a-simple-2d-camera","status":"publish","type":"post","link":"https:\/\/labalec.fr\/erwan\/?p=736","title":{"rendered":"VB.Net and XNA : Article 20 &#8211; A simple 2D camera"},"content":{"rendered":"<p>In <a href=\"https:\/\/labalec.fr\/erwan\/?p=706\" target=\"_blank\">Article 16<\/a>, we had animated a sprite.<br \/>\nNow lets enhance the demo with a 2d camera following our character creating a simple scrolling effect.<br \/>\nNote : a next article will cover parallax scrolling.<\/p>\n<p>We will simply had a camera class.<br \/>\nLets declare our camera,<br \/>\nthen instantiate it in loadcontent passing the width and height,<br \/>\n<code><br \/>\ncam = New camera(graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height)<br \/>\n<\/code><br \/>\nupdate it,<br \/>\n<code><br \/>\ncam.setfocalpoint(New Vector2(dest_box.X, dest_box.Y), New Vector2(graphics.PreferredBackBufferWidth * 1.5 + 32, graphics.PreferredBackBufferHeight * 1.5 + 32))<br \/>\ncam.update()<br \/>\n<\/code><br \/>\nand finally use it in our draw method thru a parameter in the spritebatch.begin method<br \/>\n<code><br \/>\nspriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Nothing, Nothing, Nothing, Nothing, cam.viewmatrix)<br \/>\n<\/code><\/p>\n<p>The camera class is itself extremely simple (note that we will manage zoom and rotation also later)<br \/>\n<code><br \/>\nImports Microsoft.Xna.Framework<br \/>\nPublic Class camera<br \/>\n    Public position As Vector2<br \/>\n    Public viewmatrix As Matrix<br \/>\n    Dim _screenx As Integer<br \/>\n    Dim _screeny As Integer<br \/>\n    Public Sub New(SizeX As Integer, sizeY As Integer)<br \/>\n        _screenx = SizeX<br \/>\n        _screeny = sizeY<br \/>\n    End Sub<\/p>\n<p>    Public Sub setfocalpoint(focalposition As Vector2)<br \/>\n        position = New Vector2(focalposition.X - _screenx \/ 2, focalposition.Y - _screeny \/ 2)<br \/>\n        If position.X < 0 Then position.X = 0\n        If position.Y < 0 Then position.Y = 0\n    End Sub\n\n    Public Sub setfocalpoint(ByVal focalposition As Vector2, ByVal lock As Vector2)\n        If focalposition.X > lock.X Then focalposition.X = lock.X<br \/>\n        If focalposition.Y > lock.Y Then focalposition.Y = lock.Y<\/p>\n<p>        position = New Vector2(focalposition.X - _screenx \/ 2, focalposition.Y - _screeny \/ 2)<\/p>\n<p>        If position.X < 0 Then position.X = 0\n        If position.Y < 0 Then position.Y = 0\n    End Sub\n\n    Public Sub update()\n        viewmatrix = Matrix.CreateTranslation(New Vector3(-position, 0))\n    End Sub\nEnd Class\n<\/code><\/p>\n<p>The video illustrating this.<br \/>\n<div style=\"width: 695px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-736-1\" width=\"695\" height=\"521\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/labalec.fr\/erwan\/wp-content\/uploads\/2013\/12\/xna_demo_17.mp4?_=1\" \/><a href=\"https:\/\/labalec.fr\/erwan\/wp-content\/uploads\/2013\/12\/xna_demo_17.mp4\">https:\/\/labalec.fr\/erwan\/wp-content\/uploads\/2013\/12\/xna_demo_17.mp4<\/a><\/video><\/div><\/p>\n<p>The source code.<br \/>\n<a href=\"https:\/\/labalec.fr\/erwan\/wp-content\/uploads\/2013\/12\/xna_demo_23.2.zip\">xna_demo_23.2<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Article 16, we had animated a sprite. Now lets enhance the demo with a 2d camera following our character creating a simple scrolling effect. Note : a next article will cover parallax scrolling. We will simply had a camera class. Lets declare our camera, then instantiate it in loadcontent passing the width and height, <a href='https:\/\/labalec.fr\/erwan\/?p=736' class='excerpt-more'>[&#8230;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[34,35],"tags":[],"class_list":["post-736","post","type-post","status-publish","format-standard","hentry","category-dotnet","category-xna","category-34-id","category-35-id","post-seq-1","post-parity-odd","meta-position-corners","fix"],"_links":{"self":[{"href":"https:\/\/labalec.fr\/erwan\/index.php?rest_route=\/wp\/v2\/posts\/736","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/labalec.fr\/erwan\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/labalec.fr\/erwan\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/labalec.fr\/erwan\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/labalec.fr\/erwan\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=736"}],"version-history":[{"count":2,"href":"https:\/\/labalec.fr\/erwan\/index.php?rest_route=\/wp\/v2\/posts\/736\/revisions"}],"predecessor-version":[{"id":740,"href":"https:\/\/labalec.fr\/erwan\/index.php?rest_route=\/wp\/v2\/posts\/736\/revisions\/740"}],"wp:attachment":[{"href":"https:\/\/labalec.fr\/erwan\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=736"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/labalec.fr\/erwan\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=736"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/labalec.fr\/erwan\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=736"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}