Cabrera / Bakhirev / Marsh | Beginning iPhone Games Development | E-Book | www2.sack.de
E-Book

E-Book, Englisch, 728 Seiten

Cabrera / Bakhirev / Marsh Beginning iPhone Games Development


1. ed
ISBN: 978-1-4302-2600-0
Verlag: Apress
Format: PDF
Kopierschutz: 1 - PDF Watermark

E-Book, Englisch, 728 Seiten

ISBN: 978-1-4302-2600-0
Verlag: Apress
Format: PDF
Kopierschutz: 1 - PDF Watermark



iPhone games are hot! Just look at the numbers. Games make up over 25 percent of total apps and over 70 percent of the most popular apps. Surprised? Of course not! Most of us have filled our iPhone or iPod touch with games, and many of us hope to develop the next best-selling, most talked-about game. You've probably already read and mastered Beginning iPhone 3 Development; Exploring the iPhone SDK, the best-selling second edition of Apress's highly acclaimed introduction to the iPhone and iPod touch by developers Dave Mark and Jeff LaMarche. This book is the game-specific equivalent, providing you with the same easy-to-follow, step-by-step approach, more deep technical insights, and that familiar friendly style. While games are all about fun, at the same time, they're serious business. With this Beginning iPhone Games Development book, you're going to roll up your sleeves and get your hands dirty with some hardcore coding. While you may have written games before, this book will take you further, immersing you in the following topics: Game graphics and animation with UIKit, Quartz, Core Animation, and OpenGL ES Game audio with OpenAL, MediaPlayer Framework, AV Foundation, and AudioSession Game networking with GameKit, Bonjour, and Internet sharing For those looking for iPad game development coverage and/or iOS 5 SDK specific game coverage, check out the published Beginning iOS 5 Games Development by Lucas Jordan from Apress.

PJ Cabrera is a software engineer with more than 12 years of experience developing information systems in various industries, programming in C, C++, Java, PHP, Python, and Ruby. But his real passion for many years has been hacking gadgets (i.e., turning a Sega Dreamcast into a NetBSD router, or running Android and Debian GNU/Linux on a Palm TX) and making home-brewed games for consoles such as Dreamcast, PlayStation 2, GameBoy Advance, and PSP. He is very excited that he can finally share his creative side on iPhone and XBox 360 with the general public through the App Store and XNA Community Games.

Cabrera / Bakhirev / Marsh Beginning iPhone Games Development jetzt bestellen!

Weitere Infos & Material


1;Title Page
;1
2;Copyright Page
;2
3;Contents at a Glance;4
4;Table of Contents
;5
5;About the Authors;13
6;About the Technical Reviewer
;15
7;Acknowledgments;16
8;Introduction;17
9;Chapter 1 A Revolutionary Gaming Platform: Games for Everyone, Anytime, Anywhere
;18
9.1;The Ever-Present iPhone;18
9.2;Mass Appeal—There’s a Gamer Born Every Minute;19
9.3;User Interfaces—Death of the D-Pad;21
9.4;Connectivity—Plays Well with Others;22
9.5;User Data—This Time It’s Personal;23
9.6;Device Performance—A Multimedia Powerhouse;25
9.7;Dev Kit? You’re Holding It!;26
9.8;Innovation—Good Things Come from Small Developers
;27
9.9;Summary;28
10;Chapter 2 Developing iPhone Games: Peeking Inside the iPhone Toolbox
;29
10.1;Development Tools and Environment;29
10.2;UIKit;30
10.3;Quartz 2D and Core Animation;31
10.4;OpenGL ES;32
10.5;Audio APIs;33
10.6;Networking;34
10.7;Summary;35
11;Chapter 3 Moving Images on a Small Screen—UIKit Controls
;36
11.1;A Quick Introduction to Cocoa Touch;36
11.1.1;The Objective-C Language;37
11.1.1.1;A Brief Objective-C Example;37
11.1.1.2;Using an Objective-C Class;41
11.1.1.3;Memory Management in Objective-C;43
11.1.2;Cocoa Touch and the UIKit Framework;44
11.1.2.1;Introducing UIView;45
11.1.2.1.1;The Frame Property;45
11.1.2.1.2;The Background Color and Alpha Properties;47
11.1.2.1.3;The Center Property;47
11.2;Building a Simple Game;48
11.2.1;Creating an Xcode Project;48
11.2.2;Creating the IVBricker User Interface;50
11.2.2.1;Examining the Main Window File;50
11.2.2.2;Examining the View Controller File;52
11.2.2.3;Setting View Properties;52
11.2.2.4;Adding Components to the View;53
11.2.2.5;Adding Code to the View Controller;55
11.2.2.6;Connecting a Property with a Component;56
11.2.3;Snazzy Graphics Make the Grade;57
11.2.3.1;Adding the Image;57
11.2.3.2;The Illusion of Motion;59
11.2.3.3;Rocking and Grooving with User Input;61
11.2.3.4;Handling Accelerometer Input;63
11.2.3.5;Handling Touchscreen Input;64
11.2.3.6;When Objects Collide;65
11.2.3.7;Failure Conditions;66
11.2.3.8;Winning Conditions;72
11.2.3.8.1;Loading and Displaying Images Programmatically;72
11.2.3.8.2;Creating the Grid of Bricks;74
11.2.3.8.3;Detecting image View Collisions;76
11.2.3.9;Changing the Timer to CADisplayLink;79
11.3;The End?;81
11.4;Application Delegate Events;82
11.4.1;Application Termination;82
11.4.2;Application Interruptions;83
11.4.3;Low Memory Warnings;83
11.5;Saving and Loading Game State;84
11.5.1;Managing Memory with a Custom Image Loader;86
11.6;Animating Images;87
11.6.1;Using the UIImageView Animation Properties;87
11.6.2;Using NSTimer for Animation;89
11.6.3;Using CADisplayLink for Animation;90
11.7;Summary;93
12;Chapter 4 She Shoots, She Hits, She Scores!
;94
12.1;Quartz 2D Game Overview;94
12.2;Every Artist Needs a Canvas;96
12.3;Your First Graphic with Quartz 2D;104
12.3.1;Saving and Restoring the Context;105
12.3.2;Adding Color;107
12.4;Sprites;108
12.4.1;Creating the Sprite Class;108
12.4.2;Using the Sprite Class;114
12.5;Which Way Is Up?;117
12.5.1;Changing to Landscape Orientation;117
12.5.2;Centering the Origin;119
12.6;Vector Art;120
12.6.1;Creating the VectorSprite Class;121
12.6.2;Using the VectorSprite Class;124
12.7;Flipbook Animations;127
12.7.1;Creating the AtlasSprite Class;128
12.7.2;Modifying the Sprite Class;133
12.7.3;Using the AtlasSprite Class;134
12.8;Heads-Up Displays;138
12.8.1;Creating the TextSprite Class;138
12.8.2;Using the TextSprite Class;144
12.9;Asteroids Game Architecture;145
12.9.1;The Asteroids Game Loop;145
12.9.2;The Asteroids Model;146
12.9.3;The Asteroids View;148
12.9.4;The Asteroids Game Controller;149
12.10;Conclusion;151
13;Chapter 5 Flipping Out and Sweeping Away with Core Animation
;152
13.1;Core Animation Sample Project Overview;153
13.2;Animating UIViews;155
13.2.1;Simple Movement;158
13.2.2;Animation Curves;159
13.2.3;Reverse and Repeat;161
13.2.4;Delay, Ease-In, and Ease-Out;163
13.2.5;UIView Transforms;164
13.2.6;UIView Transitions;166
13.3;Animating Core Animation Layers;168
13.3.1;Implicit Animations;169
13.3.2;Timing Functions;169
13.3.3;Layer Animation Transitions;170
13.3.3.1;Fade;171
13.3.3.2;Move In, Push, and Reveal;173
13.4;Summary;174
14;Chapter 6 OpenGL Basics: Wrapping Your Head Around the OpenGL API
;175
14.1;What Is OpenGL ES and Why Do I Care?;175
14.2;Understanding the 3D World;176
14.3;Matrix Basics: Taking the Red Pill;178
14.3.1;Bringing It All Together;181
14.3.2;Matrix Types;181
14.3.2.1;The Model and the Model Matrix;182
14.3.2.2;The View Matrix;182
14.3.2.3;The Projection;182
14.3.2.4;The Viewport;182
14.3.3;Stateful API;182
14.4;Rendering Basics;183
14.5;The Basic Game Template;184
14.6;Wrapping the CAEAGLLayer in a View: EAGLView;186
14.6.1;First Steps: The Init Method;187
14.6.2;Frame Buffers, Render Buffers, and Depth Buffers;189
14.6.3;Seeing into the OpenGL World;192
14.6.4;Drawing and Rendering;197
14.7;How to Draw Stuff with OpenGL;198
14.7.1;The Scene and Mesh Objects;198
14.7.2;Pushing and Popping Matrixes;201
14.7.3;Putting Your Objects in the Scene;201
14.7.3.1;Moving Objects;201
14.7.3.2;Scaling Objects;202
14.7.3.3;Spinning Objects;202
14.7.4;Defining Your Object in 3D Space;204
14.7.4.1;Vertex and Color Information;204
14.7.4.2;Understanding Triangles;206
14.8;The Game Loop and the Timer;208
14.9;The Input Controller;213
14.10;The App Delegate;214
14.11;Summary;214
15;Chapter 7 Putting It Together: Making a Game in OpenGL
;216
15.1;Space Rocks! Game Design;216
15.2;Getting Started with the Template;218
15.3;Rotation Makes the World Go 'Round;219
15.4;3D Point Upgrade;222
15.5;Adding Buttons;224
15.5.1;Creating a Button Object;225
15.5.2;Working with Vertex Data;226
15.5.3;Storing Buttons;228
15.5.4;Detecting Touches;231
15.5.5;Wiring Up the Buttons;236
15.6;Building a Better Spaceship;237
15.6.1;Going Mobile;237
15.6.2;Adding the Spaceship;237
15.6.3;Adding and Removing Scene Objects;240
15.6.4;Falling Off the Edge of the Screen;242
15.7;Space Rocks!;243
15.8;Adding Missiles;247
15.8.1;Firing Missiles;247
15.8.2;Removing Unwanted Missiles;248
15.9;Making Nicer Buttons;249
15.10;Collision Detection;251
15.10.1;What Is a Collision?;251
15.10.2;Collision-Detection Techniques;252
15.10.2.1;Optimized Collision Detection;253
15.10.2.2;Radius-to-Radius Collision Check;254
15.11;Collisions on the Rocks;257
15.11.1;Centroid and Radius;257
15.11.2;Colliders and Collidees;259
15.11.2.1;Take the Red Pill: The Transform Matrix;259
15.11.2.2;The Collider Object;261
15.11.2.3;The Collision Controller Object;263
15.11.2.4;Back to the Scene Controller;264
15.11.2.5;Scene Object Updates;265
15.11.3;Collision Checking Redux;268
15.12;Summary;271
16;Chapter 8 The Next Steps: Atlases, Sprites, and Particles—Oh My!
;273
16.1;Textures and Texture Atlases;273
16.1.1;What Is a Texture Anyway, and Why Do I Care?;274
16.1.2;Getting Image Data into OpenGL;275
16.1.3;Binding Textures;279
16.1.4;UV Is Not Bad for Your Skin;280
16.1.5;You Get a Textured Quad!;281
16.1.6;Say Hello to the Texture Atlas;284
16.1.7;Switching the Old and Busted for the New Hotness;288
16.1.8;A Nicer User Interface;288
16.1.9;Colors with Textures;290
16.2;Sprite Animation;292
16.2.1;Frame Rate Independence;294
16.2.2;Animations for Everything;298
16.3;From 2D to 3D;299
16.3.1;It’s Only One More D—What’s the Big Deal?;300
16.3.2;Where Do 3D Models Come From?;301
16.3.3;From Modeler to Screen;302
16.3.4;What Is Normal?;303
16.3.5;Standardizing on GL_TRIANGLES;303
16.3.6;Textures Plus Models;305
16.3.7;Shadows Define Shape;307
16.3.8;Depth Buffer and Face Culling;310
16.3.9;Collision Detection Tweaks;312
16.4;Particle Systems Add Life to Your Game;313
16.4.1;What Is a Particle System?;313
16.4.2;A Lot of Random Numbers;314
16.4.3;The Nitty-Gritty of a Particle System: Particles;315
16.4.4;Particle Emitters and You;316
16.4.5;Tuning Our System;323
16.4.6;Particle Systems for Everything;324
16.4.7;What the Future Holds: Shaders;325
16.5;Summary;325
17;Chapter 9 Introduction to Core Audio
;327
17.1;Audio Services Provided by Core Audio;327
17.1.1;Audio Units;328
17.1.2;Audio File Services;329
17.1.3;Audio File Stream Services;329
17.1.4;Audio Conversion Services;329
17.1.5;Extended Audio File Services;329
17.1.6;Audio Session Services;330
17.1.7;System Sound Services;330
17.1.8;Audio Queue Services;330
17.1.9;AVFoundation;331
17.1.10;OpenAL;331
17.2;The Core Audio Frameworks;332
17.3;Codecs and File Formats;333
17.3.1;Codecs Supported by Core Audio;334
17.3.2;File Formats Supported by Core Audio;335
17.3.3;Using afconvert to Convert Between Formats;336
17.3.4;Hardware-Accelerated Codecs: Restricted and Unrestricted Codec Groups
;337
17.3.5;Codec and File Format Suggestions;338
17.4;Alerts and Vibration: Introducing System Sound Services
;339
17.4.1;The Case Against System Sound Services for General Sound Effects
;340
17.4.2;A System Sound Services Example;341
17.4.3;A Comment on Asynchronous Playback;347
17.5;Setting Policies for Your Audio: Introducing Audio Session Services
;348
17.5.1;Boilerplate Code and Procedures for Using Audio Session Services
;350
17.5.2;Detecting Hardware and Getting Properties;352
17.6;Easy Audio Playback in Objective-C with AVFoundation
;353
17.7;Mission Complete…but Our Princess Is in Another Castle!
;363
18;Chapter 10 Making Noise with OpenAL
;365
18.1;OpenAL Overview;366
18.1.1;What OpenAL Supports;366
18.1.2;Some History of OpenAL;366
18.2;My Story and Goals for Audio Coverage;370
18.3;Roadmap for the Audio Coverage;371
18.4;Setting Up Basic Sound in OpenAL;372
18.4.1;Setting Up an Audio Session;373
18.4.2;Opening a Device;374
18.4.2.1;Advanced OpenAL Tip: Specifying OpenAL Devices;375
18.4.3;Creating a Context;377
18.4.3.1;Advanced Tip: Using Attribute Lists;377
18.4.4;Activating the Context;378
18.4.5;Generating Sound Sources;379
18.4.6;Generating Data Buffers;380
18.4.7;Loading Sound Data from Files;380
18.4.8;Submitting Sound Data to OpenAL Data Buffers;384
18.4.8.1;Advanced OpenAL Tip: The alBufferDataStatic Extension;384
18.4.9;Attaching a Data Buffer to a Sound Source;386
18.4.10;Playing Sound;386
18.4.11;Shutting Down and Cleaning Up;387
18.4.11.1;Cow Launched!;388
18.5;Exposing Flaws and the Missing Details;388
18.5.1;Adding More Sounds;390
18.5.2;Problems to Notice;394
18.5.3;OpenAL Error Checking;395
18.5.4;Audio Session Interruptions;396
18.5.5;OpenAL Extensions for iPhone OS;400
18.5.6;Performance Notes;400
18.5.7;OpenAL Source Limits: “It’s a Secret to Everybody”;402
18.6;Sound Resource Manager: Fixing the Design;404
18.6.1;Overview of the Resource Manager;405
18.6.2;Initial Cleanup;407
18.6.3;The Sound File Database (Cache System);412
18.6.4;OpenAL Source Management (Reserving and Recycling);416
18.6.5;Integration with Space Rocks!;420
18.6.5.1;SoundDidFinishPlaying Callbacks;424
18.6.5.2;Final Integration Steps for Space Rocks!;426
18.6.6;Handling When All Available Sources Are Exhausted;431
18.6.7;Final Demo Embellishments;431
18.7;Save Point Reached;434
19;Chapter 11 3D Audio—Turning Noise into Game Sounds
;435
19.1;The Design of OpenAL: Sources, Buffers, and Listeners
;435
19.2;Limits of 3D Audio in OpenAL;438
19.3;Integrating the Listener into Space Rocks!;438
19.3.1;Creating the Listener Class;439
19.3.2;Picking the Designated Driver;440
19.4;Adding Positions to Sounds;441
19.4.1;Handling Initial Positioning on Creation;443
19.4.2;Disabling Distance Attenuation;444
19.4.2.1;Working Around an alDistanceModelBug: Disabling Attenuation on a Per-Source Basis
;445
19.5;Listener Orientation;446
19.5.1;Right-Handed Coordinate Systems and the Right-Hand Rule;446
19.5.2;Unit Circle, Polar-to-Rectangular Coordinates, Phase Shifting, and Trigonometric Identities
;449
19.5.3;Integration into Space Rocks!;451
19.6;Source Direction and Cones;453
19.6.1;Inner Cone, Outer Cone, and Transitional Zone;453
19.6.2;Implementation Time;455
19.7;Velocity and the Doppler Effect;456
19.7.1;Velocities and Scaling Factors;458
19.7.2;Doppler Effect Example Time;459
19.8;Distance Attenuation;460
19.8.1;Attenuation Models;461
19.8.1.1;Inverse Distance;461
19.8.1.2;Inverse Distance Clamped;462
19.8.1.3;Linear Distance;462
19.8.1.4;Linear Distance Clamped;463
19.8.1.5;Exponential Distance;464
19.8.1.6;Exponential Distance Clamped;465
19.8.1.7;Distance Attenuation Parameters;466
19.8.1.8;Picking a Distance Model;467
19.8.2;Back to Space Rocks!;468
19.9;Using Relative Sound Properties to Selectively Disable 3D Effects
;471
19.10;Achievement Unlocked: Use All OpenAL 3D Features;473
20;Chapter 12 Streaming: Thumping, Pulse-Quickening Game Excitement
;475
20.1;Music and Beyond;475
20.2;iPod Music Library (Media Player Framework);478
20.2.1;Playing iPod Music in Space Rocks!;480
20.2.2;Adding a Media Item Picker;482
20.2.3;Shake It! (Easy Accelerometer Shake Detection);485
20.3;Audio Streaming;486
20.3.1;AVFoundation-Based Background Music for Space Rocks!;487
20.3.1.1;The Playback Sound Controller;488
20.3.1.2;Integration into Space Rocks!;491
20.3.2;OpenAL Buffer Queuing Introduction;493
20.3.2.1;Initialization;495
20.3.2.2;Unqueuing;497
20.3.2.3;Queuing;498
20.3.2.4;Buffer Underrun;499
20.3.2.5;Pausing;500
20.3.2.6;Fast Forwarding and Rewinding;500
20.3.2.7;Startup Number of Buffers and Filling the Queue;500
20.3.2.8;How to Choose the Number and Size of Buffers;501
20.3.3;OpenAL-Based Background Music for Space Rocks!;502
20.3.3.1;A New Buffer Data Class for Streaming;502
20.3.3.2;Unqueue the Processed Buffers;507
20.3.3.3;Queue a New Buffer If Necessary;508
20.3.3.4;Handle a Buffer Underrun;509
20.3.3.5;Handle EOF and Finished Playing;509
20.3.3.6;OpenALSoundController Changes;510
20.3.3.7;BBSceneController Integration;513
20.3.3.8;Analysis: Number of Buffers and Buffer Sizes;514
20.3.3.9;Star Power Ready!;515
20.3.4;OpenAL Speech for Space Rocks!;515
20.3.4.1;EWSoundSourceObject: Finishing the implementation;517
20.3.4.2;BBSceneController: Adding a New UFO;517
20.3.4.3;UFO: Taunting and Callbacks;518
20.3.4.4;The alBufferDataStatic Crashing Bug;521
20.3.4.4.1;Work-Arounds;523
20.3.5;Audio Queue Services Based Background Music for Space Rocks!
;525
20.3.5.1;Rewind and Looping;526
20.3.5.2;Audio Session Interruptions;527
20.3.6;Perfect Full Combo!;528
20.4;Audio Capture;528
20.4.1;Audio Capture APIs;530
20.4.2;AVFoundation: File Recording with AVAudioRecorder;531
20.4.3;OpenAL: Capture Oscilloscope;536
20.4.3.1;The Capture APIs;539
20.4.3.2;ALC Device Enumeration;539
20.4.3.3;Capturing Audio;540
20.5;Back to OpenGL;543
20.5.1;Vertex Buffer Objects;543
20.5.2;Some Notes on OpenGL and OpenAL Optimization;545
20.6;The End of the Audio Road;547
21;Chapter 13 Networking for iPhone Games: Introduction
;549
21.1;Meet the Network;549
21.1.1;Network Interfaces;550
21.1.2;TCP/IP;550
21.1.3;Bonjour;552
21.2;iPhone SDK and Networking;552
21.2.1;Sockets and Connections;552
21.2.2;BSD Socket API;553
21.2.3;CFNetwork;553
21.2.4;NSNetServices;553
21.2.5;GameKit
;553
21.3;Summary;554
22;Chapter 14 Going Head to Head
;555
22.1;Hello Pong!;555
22.2;Using Peer Picker to Find a Human Opponent;556
22.2.1;What Does It Look Like?;561
22.2.2;How Does It Work?;564
22.3;Making the Connection;565
22.4;Sending and Receiving Messages;568
22.4.1;Rolling the Dice;569
22.4.2;Ready…Set…Go!;577
22.4.3;Hits and Misses;579
22.4.4;The Paddle Comes Alive;587
22.5;Game Over: Handling Disconnects;592
22.6;Summary;593
23;Chapter 15 Party Time
;595
23.1;8 x 3 = ?;595
23.1.1;Starting Point;595
23.1.2;Where Are We Going?;598
23.1.3;What’s in the Structure?;599
23.2;Making Connections;601
23.2.1;Introducing the Connection and Stream Objects;601
23.2.2;Connection Initialization;603
23.2.3;Closing and Cleanup;604
23.2.4;Reading Data;605
23.2.5;Writing Data;608
23.2.6;Handling Stream Events;609
23.2.7;The Complete Picture;609
23.3;Socket Servers;610
23.3.1;The SocketServer Class;610
23.3.2;Socket Server Initialization;611
23.3.3;Publishing via Bonjour;614
23.3.4;Starting and Stopping;615
23.4;Finding Servers via Bonjour;616
23.4.1;Looking for Servers;617
23.4.2;Connecting to Servers;619
23.4.3;Final Details;621
23.5;Implementing the Game Client;625
23.5.1;Tracing the Logic;625
23.5.2;Choosing the Network Message Format;628
23.5.3;Making It Talk;630
23.5.4;Hooking It Up;633
23.6;Implementing the Game Server;634
23.6.1;Managing Players;635
23.6.2;Laying It Out;637
23.6.3;Initialization;642
23.6.4;Players Joining and Leaving;643
23.6.5;Starting and Stopping Game Rounds;644
23.6.6;Collecting and Processing Answers;647
23.6.7;Hooking It Up;648
23.7;Summary;648
24;Chapter 16 Connecting with the Outside World
;649
24.1;Challenges;649
24.1.1;Au Revoir, Bonjour!;649
24.1.2;No GameKit Peer-to-Peer for You!;650
24.1.3;Server, interrupted;650
24.1.4;Lag;651
24.1.5;It’s All Greek to Me…;651
24.1.6;And a Bunch More;652
24.2;Basics of Online Game Play;653
24.2.1;Client/Server Games;653
24.2.2;Connecting to a Game Server Without Bonjour;654
24.2.3;Peer-to-Peer Games;655
24.2.4;Something About Reinventing the Wheel;656
24.2.5;Like a Drop in the Ocean;657
24.3;Making Games More Social;657
24.3.1;Sharing High Scores Online;657
24.3.2;Chasing Ghosts;659
24.3.3;Chatting;659
24.4;Summary;660
25;Chapter 17 Putting It All Together: Now Comes the Fun Part
;661
25.1;What We’ve Covered;661
25.2;Some Game Design Tips;662
25.3;Wrapping It Up;663
26;Index;664



Ihre Fragen, Wünsche oder Anmerkungen
Vorname*
Nachname*
Ihre E-Mail-Adresse*
Kundennr.
Ihre Nachricht*
Lediglich mit * gekennzeichnete Felder sind Pflichtfelder.
Wenn Sie die im Kontaktformular eingegebenen Daten durch Klick auf den nachfolgenden Button übersenden, erklären Sie sich damit einverstanden, dass wir Ihr Angaben für die Beantwortung Ihrer Anfrage verwenden. Selbstverständlich werden Ihre Daten vertraulich behandelt und nicht an Dritte weitergegeben. Sie können der Verwendung Ihrer Daten jederzeit widersprechen. Das Datenhandling bei Sack Fachmedien erklären wir Ihnen in unserer Datenschutzerklärung.